Fixed-point arithmetic library

Discussion in 'Java' started by Tom Anderson, Feb 22, 2012.

  1. Tom Anderson

    Tom Anderson Guest

    Evening all,

    I would quite like to represent some numbers in fixed point, and do
    arithmetic with them.

    These numbers will mostly not be more than a bilion, and will probably
    never be more than a hundred billion. Some of them, i will need to
    represent to eight decimal places. I'd like to be able to multiply two
    large numbers, but i suspect will not need to multiply three. 11 * 2 + 8 =
    30 decimal digits; that's about 100 bits, so 128 bits would be big enough
    (about 5 decimal digits of headroom).

    Can anyone suggest an existing library for doing fixed-point arithmetic
    which would cover this?

    I have googled, but not found anything. There are a few fixed-precision
    libraries aimed at J2ME (i assume because old phones didn't have
    floating-point units?). There's something called jExigo, but it's 64-bit
    and the code doesn't look great.

    It's quite possible that there is no such library. But i thought it
    prudent to ask before writing one myself.

    Thanks,
    tom

    --
    An artist is attracted to certain kinds of form without knowing why. You
    adopt a position intuitively; only later do you attempt to rationalize
    or even justify it. -- Fernando Botero
     
    Tom Anderson, Feb 22, 2012
    #1
    1. Advertising

  2. Tom Anderson

    Jan Burse Guest

    If a decimal scale suits you, you could use:

    http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

    Decimal scale means your numbers would be represented as:

    mantissa * 10 ^ -scale

    Bye

    Tom Anderson schrieb:
    > Evening all,
    >
    > I would quite like to represent some numbers in fixed point, and do
    > arithmetic with them.
    >
    > These numbers will mostly not be more than a bilion, and will probably
    > never be more than a hundred billion. Some of them, i will need to
    > represent to eight decimal places. I'd like to be able to multiply two
    > large numbers, but i suspect will not need to multiply three. 11 * 2 + 8
    > = 30 decimal digits; that's about 100 bits, so 128 bits would be big
    > enough (about 5 decimal digits of headroom).
    >
    > Can anyone suggest an existing library for doing fixed-point arithmetic
    > which would cover this?
    >
    > I have googled, but not found anything. There are a few fixed-precision
    > libraries aimed at J2ME (i assume because old phones didn't have
    > floating-point units?). There's something called jExigo, but it's 64-bit
    > and the code doesn't look great.
    >
    > It's quite possible that there is no such library. But i thought it
    > prudent to ask before writing one myself.
    >
    > Thanks,
    > tom
    >
     
    Jan Burse, Feb 22, 2012
    #2
    1. Advertising

  3. On 22.02.2012 22:39, Tom Anderson wrote:
    > Evening all,
    >
    > I would quite like to represent some numbers in fixed point, and do
    > arithmetic with them.


    Fixed point math is susceptible to precision issues which can be more
    severe than those of float and double: 0.01 * 0.2 -> 0.00

    http://en.wikipedia.org/wiki/Fixed_point_arithmetic#Precision_loss_and_overflow

    Out of curiosity: What do you want to do with that?

    > These numbers will mostly not be more than a bilion, and will probably
    > never be more than a hundred billion. Some of them, i will need to
    > represent to eight decimal places. I'd like to be able to multiply two
    > large numbers, but i suspect will not need to multiply three. 11 * 2 + 8
    > = 30 decimal digits; that's about 100 bits, so 128 bits would be big
    > enough (about 5 decimal digits of headroom).
    >
    > Can anyone suggest an existing library for doing fixed-point arithmetic
    > which would cover this?
    >
    > I have googled, but not found anything. There are a few fixed-precision
    > libraries aimed at J2ME (i assume because old phones didn't have
    > floating-point units?). There's something called jExigo, but it's 64-bit
    > and the code doesn't look great.
    >
    > It's quite possible that there is no such library. But i thought it
    > prudent to ask before writing one myself.


    What about BigDecimal?
    http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html

    You could either add the precision loss after operations or just apply
    it for output.

    package math;

    import java.math.BigDecimal;
    import java.math.RoundingMode;

    public class FixedPointMath {

    public static void main(String[] args) {
    BigDecimal bd1 = new BigDecimal("0.01");
    BigDecimal bd2 = new BigDecimal("0.2");
    BigDecimal bd3 = bd1.multiply(bd2);
    BigDecimal bd4 = bd3.setScale(2, RoundingMode.HALF_UP);
    System.out.println(bd1 + " * " + bd2 + " -> " + bd3 + " -> " +
    bd4);
    }

    }

    Alternatively you could use BigInteger and add the scaling logic
    yourself when cooking your fixed math lib.

    http://docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Feb 22, 2012
    #3
  4. On Wed, 22 Feb 2012 23:13:06 +0100, Robert Klemme
    <> wrote:

    >On 22.02.2012 22:39, Tom Anderson wrote:
    >> Evening all,
    >>
    >> I would quite like to represent some numbers in fixed point, and do
    >> arithmetic with them.

    >
    >Fixed point math is susceptible to precision issues which can be more
    >severe than those of float and double: 0.01 * 0.2 -> 0.00


    Only if the target precision does not have enough decimal places.

    I have been working with fixed-point arithmetic in JavaScript so
    that I can add dollar amounts exactly. Maybe OP has something similar
    in mind, though with the number of digits of precision that he wants
    before the decimal point, I hope it is not currency-related.

    [snip]

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Feb 22, 2012
    #4
  5. On Wed, 22 Feb 2012 14:59:12 -0800, Gene Wirchenko wrote:

    > On Wed, 22 Feb 2012 23:13:06 +0100, Robert Klemme
    > <> wrote:
    >
    >>On 22.02.2012 22:39, Tom Anderson wrote:
    >>> Evening all,
    >>>
    >>> I would quite like to represent some numbers in fixed point, and do
    >>> arithmetic with them.

    >>
    >>Fixed point math is susceptible to precision issues which can be more
    >>severe than those of float and double: 0.01 * 0.2 -> 0.00

    >
    > Only if the target precision does not have enough decimal places.
    >
    > I have been working with fixed-point arithmetic in JavaScript so
    > that I can add dollar amounts exactly. Maybe OP has something similar
    > in mind, though with the number of digits of precision that he wants
    > before the decimal point, I hope it is not currency-related.
    >

    Not necessarily. BigDecimal has few surprises, but then its not fixed
    decimal. The only fixed decimal arithmetic I've done in anger was in
    Cobol, which will merrily do the following (Identification and
    Environment divisions omitted for brevity).

    DATA DIVISION.
    WORKING-STORAGE.
    01 FIXED-DECIMAL-FIELDS.
    05 FD-VALUE PIC S9(6)v9(6) COMP SYNC.
    05 FD-DIVISOR PIC S9(6)v9(6) COMP SYNC.
    05 FD-RESULT PIC S9(6)v9(6) COMP SYNC.
    05 FD-REMAINDER PIC S9(6)V9(6) COMP SYNC.

    01 DISPLAY-LINE.
    05 DL-VALUE PIC -(6)V.9(6).
    05 FILLER PIC X() VALUE " / ".
    05 DL-DIVISOR PIC -(6)V.9(6).
    05 FILLER PIC X() VALUE " = ".
    05 DL-RESULT PIC -(6)V.9(6).
    05 FILLER PIC X() VALUE " REMAINDER ".
    05 DL-REMAINDER PIC -(6)V.9(6).

    PROCEDURE DIVISION.
    MAIN SECTION.
    M-1.
    MOVE 0.8 TO FD-VALUE DL-VALUE.
    MOVE 2.0 TO FD-DIVISOR DL-DIVISOR.
    DIVIDE FD-VALUE BY FD-DIVISOR GIVING FD-RESULT REMAINDER FD-REMAINDER.
    MOVE FD-RESULT TO DL-RESULT.
    MOVE FD-REMAINDER TO DL-REMAINDER.
    DISPLAY DISPLAY-LINE.
    STOP RUN.


    This would display

    " 0.800000 / 2.000000 = 0.000000 REMAINDER 0.800000"

    because, of course, it is exactly equivalent to dividing 800000 by
    2000000 and then adding decimal points in their correct fixed positions.
    Is that what you want or is BigDecimal doing the right thing for your
    problem space?

    Apologies for not showing a Cobol SSCE, but I don't have a COBOL compiler
    available to check it.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
     
    Martin Gregorie, Feb 23, 2012
    #5
  6. Tom Anderson

    Tom Anderson Guest

    On Wed, 22 Feb 2012, Jan Burse wrote:

    > If a decimal scale suits you, you could use:
    >
    > http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html


    Decimal would be fine. BigDecimal might actually be okay too.

    I've actually misrepresented the context for this question slightly. My
    current place of work does a few calculations, and we currently use a
    fixed-point implementation of our own. However, it doesn't quite meet all
    our needs. My choice is really between extending it, and replacing it with
    something else. Being lazy, i would rather take advantage of someone
    else's hard work than do any myself.

    Now, we wrote this fixed-point implementation having previously used
    BigDecimal, because we had some serious performance problems with that.
    This was before my time, so i'm very hazy on the details. I had already
    dismissed BigDecimal out of hand on the basis of that, but it might
    actually be worth looking at again.

    I'd still be interested in any existing fixed-point libraries, as another
    option to consider.

    tom

    > Decimal scale means your numbers would be represented as:
    >
    > mantissa * 10 ^ -scale
    >
    > Bye
    >
    > Tom Anderson schrieb:
    >
    >> I would quite like to represent some numbers in fixed point, and do
    >> arithmetic with them.
    >>
    >> These numbers will mostly not be more than a bilion, and will probably
    >> never be more than a hundred billion. Some of them, i will need to
    >> represent to eight decimal places. I'd like to be able to multiply two
    >> large numbers, but i suspect will not need to multiply three. 11 * 2 + 8
    >> = 30 decimal digits; that's about 100 bits, so 128 bits would be big
    >> enough (about 5 decimal digits of headroom).
    >>
    >> Can anyone suggest an existing library for doing fixed-point arithmetic
    >> which would cover this?
    >>
    >> I have googled, but not found anything. There are a few fixed-precision
    >> libraries aimed at J2ME (i assume because old phones didn't have
    >> floating-point units?). There's something called jExigo, but it's 64-bit
    >> and the code doesn't look great.
    >>
    >> It's quite possible that there is no such library. But i thought it
    >> prudent to ask before writing one myself.


    --
    X is for ... EXECUTION!
     
    Tom Anderson, Feb 23, 2012
    #6
  7. Tom Anderson

    Tom Anderson Guest

    On Wed, 22 Feb 2012, Gene Wirchenko wrote:

    > On Wed, 22 Feb 2012 23:13:06 +0100, Robert Klemme
    > <> wrote:
    >
    >> On 22.02.2012 22:39, Tom Anderson wrote:
    >>
    >>> I would quite like to represent some numbers in fixed point, and do
    >>> arithmetic with them.

    >>
    >> Fixed point math is susceptible to precision issues which can be more
    >> severe than those of float and double: 0.01 * 0.2 -> 0.00

    >
    > Only if the target precision does not have enough decimal places.
    >
    > I have been working with fixed-point arithmetic in JavaScript so
    > that I can add dollar amounts exactly. Maybe OP has something similar
    > in mind, though with the number of digits of precision that he wants
    > before the decimal point, I hope it is not currency-related.


    It is currency-related. What's wrong with that?

    tom

    --
    Lilith doesn't exist, but it's an interesting story.
     
    Tom Anderson, Feb 23, 2012
    #7
  8. Tom Anderson

    Tom Anderson Guest

    On Thu, 23 Feb 2012, Martin Gregorie wrote:

    > The only fixed decimal arithmetic I've done in anger was in Cobol, which
    > will merrily do the following (Identification and Environment divisions
    > omitted for brevity).
    >
    > DATA DIVISION.
    > WORKING-STORAGE.
    > 01 FIXED-DECIMAL-FIELDS.
    > 05 FD-VALUE PIC S9(6)v9(6) COMP SYNC.
    > 05 FD-DIVISOR PIC S9(6)v9(6) COMP SYNC.
    > 05 FD-RESULT PIC S9(6)v9(6) COMP SYNC.
    > 05 FD-REMAINDER PIC S9(6)V9(6) COMP SYNC.
    >
    > 01 DISPLAY-LINE.
    > 05 DL-VALUE PIC -(6)V.9(6).
    > 05 FILLER PIC X() VALUE " / ".
    > 05 DL-DIVISOR PIC -(6)V.9(6).
    > 05 FILLER PIC X() VALUE " = ".
    > 05 DL-RESULT PIC -(6)V.9(6).
    > 05 FILLER PIC X() VALUE " REMAINDER ".
    > 05 DL-REMAINDER PIC -(6)V.9(6).
    >
    > PROCEDURE DIVISION.
    > MAIN SECTION.
    > M-1.
    > MOVE 0.8 TO FD-VALUE DL-VALUE.
    > MOVE 2.0 TO FD-DIVISOR DL-DIVISOR.
    > DIVIDE FD-VALUE BY FD-DIVISOR GIVING FD-RESULT REMAINDER FD-REMAINDER.
    > MOVE FD-RESULT TO DL-RESULT.
    > MOVE FD-REMAINDER TO DL-REMAINDER.
    > DISPLAY DISPLAY-LINE.
    > STOP RUN.
    >
    >
    > This would display
    >
    > " 0.800000 / 2.000000 = 0.000000 REMAINDER 0.800000"
    >
    > because, of course, it is exactly equivalent to dividing 800000 by
    > 2000000 and then adding decimal points in their correct fixed positions.


    .... right. Yes, this is indeed not great. But i don't think this is a
    correct implementation of fixed-point; what you actually have here is
    essentially integers which are being printed with a format with dots in,
    right? A fixed-point implementation of multiplication or division needs to
    do some scaling to get the right answers.

    > Is that what you want or is BigDecimal doing the right thing for your
    > problem space?


    I don't want what the COBOL does. I need to be able to divide by 2.

    tom

    --
    Lilith doesn't exist, but it's an interesting story.
     
    Tom Anderson, Feb 23, 2012
    #8
  9. On Thu, 23 Feb 2012 21:21:31 +0000, Tom Anderson
    <> wrote:

    >On Thu, 23 Feb 2012, Martin Gregorie wrote:
    >
    >> The only fixed decimal arithmetic I've done in anger was in Cobol, which
    >> will merrily do the following (Identification and Environment divisions
    >> omitted for brevity).


    [snipped COBOL code]

    >> This would display
    >>
    >> " 0.800000 / 2.000000 = 0.000000 REMAINDER 0.800000"
    >>
    >> because, of course, it is exactly equivalent to dividing 800000 by
    >> 2000000 and then adding decimal points in their correct fixed positions.

    >
    >... right. Yes, this is indeed not great. But i don't think this is a


    If you need exact decimal representation, it is good.

    >correct implementation of fixed-point; what you actually have here is
    >essentially integers which are being printed with a format with dots in,
    >right? A fixed-point implementation of multiplication or division needs to


    Well, yes, that is about what fixed-point is. Certainly, it is a
    common implementation of it.

    >do some scaling to get the right answers.


    COBOL handles the scaling automatically.

    >> Is that what you want or is BigDecimal doing the right thing for your
    >> problem space?

    >
    >I don't want what the COBOL does. I need to be able to divide by 2.


    You can do that with COBOL. Why do you think that you can not?

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Feb 23, 2012
    #9
  10. Tom Anderson

    markspace Guest

    On 2/23/2012 1:15 PM, Tom Anderson wrote:
    > ...we currently use a
    > fixed-point implementation of our own. However, it doesn't quite meet
    > all our needs.


    A big help for all of us would be to understand what needs, exactly, you
    have. What are the requirements for this class/package? Given that no
    one has offered anything besides BigDecimal, it might be moot as there
    doesn't seem to be a lot out there, but it might help narrow down any
    potential choices.

    > My choice is really between extending it, and replacing
    > it with something else. Being lazy, i would rather take advantage of
    > someone else's hard work than do any myself.


    Or you could contract out for it. :D :D Sounds like a fun little side
    project. We'd still need those requirements though.
     
    markspace, Feb 23, 2012
    #10
  11. On Thu, 23 Feb 2012 21:16:04 +0000, Tom Anderson
    <> wrote:

    >On Wed, 22 Feb 2012, Gene Wirchenko wrote:


    [snip]

    >> I have been working with fixed-point arithmetic in JavaScript so
    >> that I can add dollar amounts exactly. Maybe OP has something similar
    >> in mind, though with the number of digits of precision that he wants
    >> before the decimal point, I hope it is not currency-related.

    >
    >It is currency-related. What's wrong with that?


    You are dealing with monstrously-large numbers. National debts
    or something similar?

    If you only needed up to fifteen digits of precision total, you
    could use IEEE 754 64-bit floating point format and store integers.
    They will be stored exactly. IEEE 754 is the only number format that
    JavaScript exposes for variable types (though it does use 32-bit
    integers internally on some operations).

    I had to experiment with this, but I got it working.

    Looking up further, according to Wikipedia, there is a 128-bit
    format that has 34.02 digits of precision. If your target language
    has this format as one of its number types, you could store integers
    in such variables. You did state that you need 30 digits of
    precision, so this would fit. This would be a cheap, fairly simple
    solution.

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Feb 23, 2012
    #11
  12. On 02/23/2012 10:15 PM, Tom Anderson wrote:
    > On Wed, 22 Feb 2012, Jan Burse wrote:
    >
    >> If a decimal scale suits you, you could use:
    >>
    >> http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

    >
    > Decimal would be fine. BigDecimal might actually be okay too.
    >
    > I've actually misrepresented the context for this question slightly. My
    > current place of work does a few calculations, and we currently use a


    "few" like in "a few millions per second"?

    > fixed-point implementation of our own. However, it doesn't quite meet
    > all our needs. My choice is really between extending it, and replacing
    > it with something else. Being lazy, i would rather take advantage of
    > someone else's hard work than do any myself.
    >
    > Now, we wrote this fixed-point implementation having previously used
    > BigDecimal, because we had some serious performance problems with that.
    > This was before my time, so i'm very hazy on the details. I had already
    > dismissed BigDecimal out of hand on the basis of that, but it might
    > actually be worth looking at again.


    How long is that benchmark ago? JVMs and standard library have changed
    quite a bit during past years so the performance issues might actually
    have gone by now.

    If I would be the one responsible I'd do the measurements myself. It's
    usually better to base such decisions on hard (and current) facts. Your
    application obviously exists so you have a clear idea of the nature of
    operations you have to perform as well as the frequency of operations as
    well as the range of input data. That should make it quite easy to
    build a benchmark which realistically reflects your business case. You
    could separate the load driving from the used math implementation via
    interface (see minimalistic example below) so you can reuse the same
    tests for all the implementations you want to analyze (at least
    BigDecimal and what you built).

    Kind regards

    robert


    package clj.math;

    /**
    * Abstraction of math impl.
    *
    * @param <T>
    * type of math numbers
    * @author robert
    */
    public interface Math<T> {

    /**
    * Create a new number from int.
    *
    * @param i
    * an integer to be converted.
    * @return a number object representing the int.
    */
    T create(int i);

    /**
    * Create a new number from String.
    *
    * @param s
    * input string, must be a decimal representation of a number.
    * @return a number object representing the string.
    */
    T create(String s);

    /**
    * Addition of two numbers.
    *
    * @param a
    * a number
    * @param b
    * a number
    * @return a + b
    */
    T plus(T a, T b);

    /**
    * Multiplication of two numbers.
    *
    * @param a
    * a number
    * @param b
    * a number
    * @return a * b
    */
    T mult(T a, T b);
    }
     
    Robert Klemme, Feb 23, 2012
    #12
  13. Tom Anderson

    Lew Guest

    On 02/23/2012 02:03 PM, Gene Wirchenko wrote:
    > On Thu, 23 Feb 2012 21:16:04 +0000, Tom Anderson
    > <> wrote:
    >
    >> On Wed, 22 Feb 2012, Gene Wirchenko wrote:

    >
    > [snip]
    >
    >>> I have been working with fixed-point arithmetic in JavaScript so
    >>> that I can add dollar amounts exactly. Maybe OP has something similar
    >>> in mind, though with the number of digits of precision that he wants
    >>> before the decimal point, I hope it is not currency-related.

    >>
    >> It is currency-related. What's wrong with that?

    >
    > You are dealing with monstrously-large numbers. National debts
    > or something similar?
    >
    > If you only needed up to fifteen [decimal] digits of precision total, you
    > could use IEEE 754 64-bit floating point format and store integers.
    > They will be stored exactly. IEEE 754 is the only number format that
    > JavaScript exposes for variable types (though it does use 32-bit
    > integers internally on some operations).
    >
    > I had to experiment with this, but I got it working.
    >
    > Looking up further, according to Wikipedia, there is a 128-bit
    > format that has 34.02 [decimal] digits of precision. If your target language
    > has this format as one of its number types, you could store integers
    > in such variables. You did state that you need 30 [decimal] digits of
    > precision, so this would fit. This would be a cheap, fairly simple
    > solution.


    Are you taking into account the precision of intermediate results?

    If you multiply to 30-digit values you need 60 digits of precision to
    represent the calculation.

    This is a good time to recommend that everyone read "What Every Computer
    Scientist Should Know About Floating Point Arithmetic", by David Goldberg.

    --
    Lew
    Honi soit qui mal y pense.
    http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
     
    Lew, Feb 23, 2012
    #13
  14. Tom Anderson

    Jan Burse Guest

    You might want to implement a flexible ALU. You
    could use:

    Long: To represent [-922337203685477.5808, 922337203685477.5807]
    BigDecimal: To represent everyting that is outside of the above
    range or has not a scale 4.

    You can implement the ALU as static methods that take
    as argument the type Number.

    public class myALU {

    public Number add(Number a, Number b);
    Etc..

    }

    I did not yet do it. But I did something similar for
    arbitrary long integers. So I was dynamically switching
    between:

    Integer: To represent [2147483648, 2147483647]
    BigInteger: To represent everyting that is outside of
    the above range.

    I also used Integer.valueOf() instead of new Integer(),
    since the later works with a small cache. The overall
    performance boost was quite visible.

    I am planning to do the same for BigDecimals now. I have
    picked the range [-922337203685477.5808, 922337203685477.5807]
    since many databases (for example MS SQL Server) use this
    range and scale for a small currency/money datatype.

    Bye

    Tom Anderson schrieb:
    > On Wed, 22 Feb 2012, Jan Burse wrote:
    >
    >> If a decimal scale suits you, you could use:
    >>
    >> http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html

    >
    > Decimal would be fine. BigDecimal might actually be okay too.
    >
    > I've actually misrepresented the context for this question slightly. My
    > current place of work does a few calculations, and we currently use a
    > fixed-point implementation of our own. However, it doesn't quite meet
    > all our needs. My choice is really between extending it, and replacing
    > it with something else. Being lazy, i would rather take advantage of
    > someone else's hard work than do any myself.
    >
    > Now, we wrote this fixed-point implementation having previously used
    > BigDecimal, because we had some serious performance problems with that.
    > This was before my time, so i'm very hazy on the details. I had already
    > dismissed BigDecimal out of hand on the basis of that, but it might
    > actually be worth looking at again.
    >
    > I'd still be interested in any existing fixed-point libraries, as
    > another option to consider.
    >
    > tom
    >
    >> Decimal scale means your numbers would be represented as:
    >>
    >> mantissa * 10 ^ -scale
    >>
    >> Bye
    >>
    >> Tom Anderson schrieb:
    >>
    >>> I would quite like to represent some numbers in fixed point, and do
    >>> arithmetic with them.
    >>>
    >>> These numbers will mostly not be more than a bilion, and will probably
    >>> never be more than a hundred billion. Some of them, i will need to
    >>> represent to eight decimal places. I'd like to be able to multiply two
    >>> large numbers, but i suspect will not need to multiply three. 11 * 2 + 8
    >>> = 30 decimal digits; that's about 100 bits, so 128 bits would be big
    >>> enough (about 5 decimal digits of headroom).
    >>>
    >>> Can anyone suggest an existing library for doing fixed-point arithmetic
    >>> which would cover this?
    >>>
    >>> I have googled, but not found anything. There are a few fixed-precision
    >>> libraries aimed at J2ME (i assume because old phones didn't have
    >>> floating-point units?). There's something called jExigo, but it's 64-bit
    >>> and the code doesn't look great.
    >>>
    >>> It's quite possible that there is no such library. But i thought it
    >>> prudent to ask before writing one myself.

    >
     
    Jan Burse, Feb 23, 2012
    #14
  15. On Thu, 23 Feb 2012 21:16:04 +0000, Tom Anderson wrote:

    >
    > It is currency-related. What's wrong with that?
    >

    I take it there is a mandatory and tightly specified set of operations
    for currency conversion (or equivalent) involved in what you need to do?

    If so, I've been there and they're usually specified that way to overcome
    the deficiencies and rounding errors inherent in fixed point decimal
    arithmetic as it is/was usually implemented in assembler or COBOL on
    hardware that uses binary integers or BCD.


    --
    martin@ | Martin Gregorie
    gregorie. | Essex, UK
    org |
     
    Martin Gregorie, Feb 23, 2012
    #15
  16. On Thu, 23 Feb 2012 14:42:23 -0800, Lew <> wrote:

    >On 02/23/2012 02:03 PM, Gene Wirchenko wrote:


    [snip]

    >> Looking up further, according to Wikipedia, there is a 128-bit
    >> format that has 34.02 [decimal] digits of precision. If your target language
    >> has this format as one of its number types, you could store integers
    >> in such variables. You did state that you need 30 [decimal] digits of
    >> precision, so this would fit. This would be a cheap, fairly simple
    >> solution.

    >
    >Are you taking into account the precision of intermediate results?


    OP apparently already has. Take a look at his original post.

    >If you multiply to 30-digit values you need 60 digits of precision to
    >represent the calculation.


    His numbers are not quite THAT big.

    >This is a good time to recommend that everyone read "What Every Computer
    >Scientist Should Know About Floating Point Arithmetic", by David Goldberg.


    Yes.

    It is also worth pointing out that many *integer* values can be
    represented exactly in floating point. The emphasis on "integer" is
    deliberate.

    Sincerely,

    Gene Wirchenko
     
    Gene Wirchenko, Feb 23, 2012
    #16
  17. Tom Anderson

    Roedy Green Guest

    On Wed, 22 Feb 2012 21:39:20 +0000, Tom Anderson
    <> wrote, quoted or indirectly quoted someone who
    said :

    >These numbers will mostly not be more than a bilion, and will probably
    >never be more than a hundred billion. Some of them, i will need to
    >represent to eight decimal places


    So long max 9,223,372,036,854,775,807 would be sufficient, except for
    intermediate results? I had a similar problem back in 1985
    implementing a 32-bit forth on a 16-bit 8086 architecture.

    If your results are still 64 bits, just collecting the low order bits
    will work.

    If you need 128 bits, you could do it like this for unsigned multiply.

    split your two numbers into two 32 bit quantities

    a = bc
    d = ef


    a * d = c*f + (b*f + c*e) >> 32 + (b*e) >> 64

    In assembler this is easier since you get the high bits too as a
    matter of course from a multiply.

    If you don't need much, rolling your own based on the way you did it
    in grade 4 (considering your numbers as base 2^32 numbers rather than
    base 10). might be much easier than introducing a full library.

    In the process I bested Knuth and came up with a more efficient
    multiprecision division algorithm.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    One of the most useful comments you can put in a program is
    "If you change this, remember to change ?XXX? too".
     
    Roedy Green, Feb 25, 2012
    #17
  18. Robert Klemme <> wrote:

    (snip)
    >> I would quite like to represent some numbers in fixed point,
    >> and do arithmetic with them.


    > Fixed point math is susceptible to precision issues which can
    > be more severe than those of float and double: 0.01 * 0.2 -> 0.00


    In PL/I, if you multiply, you get the appropriate number if digits
    after the radix point.

    FIXED DECIMAL(3,2) times FIXED DECIMAL(2,1) generates a
    product of FIXED DECIMAL(5,3). If you force it to throw away
    low order digits, then, yes you can lose precision.

    -- glen
     
    glen herrmannsfeldt, Feb 27, 2012
    #18
  19. Tom Anderson

    Arne Vajhøj Guest

    On 2/26/2012 7:59 PM, glen herrmannsfeldt wrote:
    > Robert Klemme<> wrote:
    >
    > (snip)
    >>> I would quite like to represent some numbers in fixed point,
    >>> and do arithmetic with them.

    >
    >> Fixed point math is susceptible to precision issues which can
    >> be more severe than those of float and double: 0.01 * 0.2 -> 0.00

    >
    > In PL/I, if you multiply, you get the appropriate number if digits
    > after the radix point.
    >
    > FIXED DECIMAL(3,2) times FIXED DECIMAL(2,1) generates a
    > product of FIXED DECIMAL(5,3). If you force it to throw away
    > low order digits, then, yes you can lose precision.


    That is rather similar to how BigDecimal works.

    import java.math.BigDecimal;

    public class Fixed {
    public static void main(String[] args) {
    BigDecimal d1 = new BigDecimal("12.3");
    System.out.println(d1 + " " + d1.scale());
    BigDecimal d2 = new BigDecimal("4.56");
    System.out.println(d2 + " " + d2.scale());
    BigDecimal d3 = d1.multiply(d2);
    System.out.println(d3 + " " + d3.scale());
    }
    }

    12.3 1
    4.56 2
    56.088 3

    Arne
     
    Arne Vajhøj, Feb 27, 2012
    #19
  20. On 27.02.2012 02:50, Arne Vajhøj wrote:
    > On 2/26/2012 7:59 PM, glen herrmannsfeldt wrote:
    >> Robert Klemme<> wrote:
    >>
    >> (snip)
    >>>> I would quite like to represent some numbers in fixed point,
    >>>> and do arithmetic with them.

    >>
    >>> Fixed point math is susceptible to precision issues which can
    >>> be more severe than those of float and double: 0.01 * 0.2 -> 0.00

    >>
    >> In PL/I, if you multiply, you get the appropriate number if digits
    >> after the radix point.
    >>
    >> FIXED DECIMAL(3,2) times FIXED DECIMAL(2,1) generates a
    >> product of FIXED DECIMAL(5,3). If you force it to throw away
    >> low order digits, then, yes you can lose precision.

    >
    > That is rather similar to how BigDecimal works.


    And that is not exactly how FP arithmetic is described in Wikipedia:

    "For simplicity, fixed-point multiply procedures use the same result
    format as the operands. This has the effect of keeping the middle bits;
    the I-number of least significant integer bits, and the Q-number of most
    significant fractional bits. Fractional bits lost below this value
    represent a precision loss which is common in fractional multiplication.
    If any integer bits are lost, however, the value will be radically
    inaccurate."

    It boils down to how fixed "fixed" is. In my understanding decimal
    places are fixed throughout the whole calculation which is not what BD
    does (obviously to avoid precision loss).

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Feb 27, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jonathan Bromley
    Replies:
    1
    Views:
    3,905
    Jim Lewis
    Aug 15, 2003
  2. H aka N
    Replies:
    15
    Views:
    15,838
    Ben Jones
    Mar 2, 2006
  3. Satpreet
    Replies:
    1
    Views:
    490
    Michael Mair
    Feb 27, 2006
  4. Replies:
    0
    Views:
    771
  5. Saraswati lakki
    Replies:
    0
    Views:
    1,428
    Saraswati lakki
    Jan 6, 2012
Loading...

Share This Page