Double troubles - Java

This is a discussion on Double troubles - Java ; Hi There is code fragment: BigDecimal bd = new BigDecimal("9999999999.999999"); System.out.println(bd.toString()); double d = 9999999999.999999D; System.out.println(d); DecimalFormat f = (DecimalFormat) NumberFormat.getInstance(Locale.US); String s = f.format(d); System.out.println(s); f.setMinimumFractionDigits(6); s = f.format(d); System.out.println(s); Here is the result: 9999999999.999999 - good result 9.999999999999998E9 ...

+ Reply to Thread
Results 1 to 5 of 5

Double troubles

  1. Default Double troubles

    Hi
    There is code fragment:

    BigDecimal bd = new BigDecimal("9999999999.999999");
    System.out.println(bd.toString());

    double d = 9999999999.999999D;
    System.out.println(d);

    DecimalFormat f = (DecimalFormat) NumberFormat.getInstance(Locale.US);
    String s = f.format(d);
    System.out.println(s);

    f.setMinimumFractionDigits(6);
    s = f.format(d);
    System.out.println(s);

    Here is the result:

    9999999999.999999 - good result

    9.999999999999998E9

    10,000,000,000
    ~~~~~~~~~~~~~~~ precision loss

    9,999,999,999.999998
    ~~~ precision loss


    How can be avoided this precision loss in double ?

  2. Default Re: Double troubles

    Serhiy Brytskyy wrote:

    <snip>
    > 10,000,000,000
    > ~~~~~~~~~~~~~~~ precision loss
    >
    > 9,999,999,999.999998
    > ~~~ precision loss
    >
    > How can be avoided this precision loss in double ?


    You can't. Welcome to floating points.

    Every primitive type has a finite range and precision. As it happens,
    double cannot represent 9999999999.999999 exactly. It is therefore
    rounded to the nearest value that double can accommodate. Of course,
    this value is in binary, and it isn't exactly 9999999999.999998 either,
    but 9999999999.999998 is in turn the nearest to this value to six
    decimal places.

    If you need the greater precision, then you've practically answered your
    own question: use BigDecimal.

    Stewart.

    --
    My e-mail is valid but not my primary mailbox. Please keep replies on
    the 'group where everyone may benefit.

  3. Default Re: Double troubles

    Ok, but see next:

    C code

    double d = 29.0 * 0.01;
    printf("%f\n", d);
    printf("%f\n", d * 100);

    result:

    0.290000
    29.000000


    Java code:
    double d = 29.0 * 0.01;
    System.out.println(d);
    System.out.println((d * 100));

    result

    0.29
    28.999999999999996


    So, can we come to a conclusion that Java has buggy procedures with
    floating point?


    Stewart Gordon wrote:
    > Serhiy Brytskyy wrote:
    >
    > <snip>
    >
    >> 10,000,000,000
    >> ~~~~~~~~~~~~~~~ precision loss
    >>
    >> 9,999,999,999.999998
    >> ~~~ precision loss
    >>
    >> How can be avoided this precision loss in double ?

    >
    >
    > You can't. Welcome to floating points.
    >
    > Every primitive type has a finite range and precision. As it happens,
    > double cannot represent 9999999999.999999 exactly. It is therefore
    > rounded to the nearest value that double can accommodate. Of course,
    > this value is in binary, and it isn't exactly 9999999999.999998 either,
    > but 9999999999.999998 is in turn the nearest to this value to six
    > decimal places.
    >
    > If you need the greater precision, then you've practically answered your
    > own question: use BigDecimal.
    >
    > Stewart.
    >


  4. Default Re: Double troubles

    On Thu, 16 Sep 2004 20:25:41 +0300, Serhiy Brytskyy wrote:
    > Ok, but see next:
    >
    > C code
    >
    > double d = 29.0 * 0.01;
    > printf("%f\n", d);
    > printf("%f\n", d * 100);
    >
    > result:
    >
    > 0.290000
    > 29.000000
    >
    > Java code:
    > double d = 29.0 * 0.01;
    > System.out.println(d);
    > System.out.println((d * 100));
    >
    > result
    >
    > 0.29
    > 28.999999999999996
    >
    >
    > So, can we come to a conclusion that Java has buggy procedures with
    > floating point?


    No, at least not from what you've posted.

    C again:

    printf("%.15f\n",d);

    result:
    28.999999999999996

    Oh wait, lets look a tiny bit closer:

    printf("%.20f\n", d);
    printf("%.20f\n", d * 100);
    printf("%.20f\n", 0.01);

    result:
    0.28999999999999998002
    28.999999999999996
    0.01000000000000000021

    So what's your point again?

    Here's a clue: not all decimal numbers (e.g. 0.01) can be represented
    exactly in base 2.

    Here's another clue: what gets printed isn't always equal to the value
    in memory.

    And finally, a good source of more clues (warning: article contains
    actual mathematics):

    http://docs.sun.com/source/806-3568/ncg_goldberg.html

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e

  5. Default Re: Double troubles

    Ok, many thanks for detailed explanation.

    Serhiy

    Gordon Beaton wrote:
    > On Thu, 16 Sep 2004 20:25:41 +0300, Serhiy Brytskyy wrote:
    >
    >>Ok, but see next:
    >>
    >>C code
    >>
    >>double d = 29.0 * 0.01;
    >>printf("%f\n", d);
    >>printf("%f\n", d * 100);
    >>
    >>result:
    >>
    >>0.290000
    >>29.000000
    >>
    >>Java code:
    >>double d = 29.0 * 0.01;
    >>System.out.println(d);
    >>System.out.println((d * 100));
    >>
    >>result
    >>
    >>0.29
    >>28.999999999999996
    >>
    >>
    >>So, can we come to a conclusion that Java has buggy procedures with
    >>floating point?

    >
    >
    > No, at least not from what you've posted.
    >
    > C again:
    >
    > printf("%.15f\n",d);
    >
    > result:
    > 28.999999999999996
    >
    > Oh wait, lets look a tiny bit closer:
    >
    > printf("%.20f\n", d);
    > printf("%.20f\n", d * 100);
    > printf("%.20f\n", 0.01);
    >
    > result:
    > 0.28999999999999998002
    > 28.999999999999996
    > 0.01000000000000000021
    >
    > So what's your point again?
    >
    > Here's a clue: not all decimal numbers (e.g. 0.01) can be represented
    > exactly in base 2.
    >
    > Here's another clue: what gets printed isn't always equal to the value
    > in memory.
    >
    > And finally, a good source of more clues (warning: article contains
    > actual mathematics):
    >
    > http://docs.sun.com/source/806-3568/ncg_goldberg.html
    >
    > /gordon
    >


+ Reply to Thread

Similar Threads

  1. fast copy from double[] to double[,]
    By Application Development in forum CSharp
    Replies: 2
    Last Post: 10-05-2007, 10:02 AM
  2. Replies: 0
    Last Post: 05-14-2007, 08:13 AM
  3. Re: editablemovie / qtsoundtrack troubles + more troubles
    By Application Development in forum basic.visual
    Replies: 3
    Last Post: 04-26-2005, 12:56 PM
  4. Replies: 10
    Last Post: 04-12-2004, 02:27 AM
  5. Error in "double = double - double" statement
    By Application Development in forum basic.visual
    Replies: 3
    Last Post: 01-23-2004, 06:06 AM