Problem with a double

Discussion in 'Java' started by jorgeba, Dec 9, 2007.

  1. jorgeba

    jorgeba Guest

    Hi,

    I have an amazing problem with a double in Java.

    for (double i = 0; i<1; i=i+0.2)
    System.out.println (i);

    Output:
    0
    0.2
    0.399999999 !!!!!!!!!!!
    0.6
    0.8

    It is amazing! Does someone understand it?

    Thank you in advance,
    Jorge
    jorgeba, Dec 9, 2007
    #1
    1. Advertising

  2. jorgeba

    Daniel Pitts Guest

    jorgeba wrote:
    > Hi,
    >
    > I have an amazing problem with a double in Java.
    >
    > for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    > Output:
    > 0
    > 0.2
    > 0.399999999 !!!!!!!!!!!
    > 0.6
    > 0.8
    >
    > It is amazing! Does someone understand it?
    >
    > Thank you in advance,
    > Jorge

    This is not specific to Java. This has to do with the way doubles are
    stored in memory, and the way they are rounded before display.


    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Dec 9, 2007
    #2
    1. Advertising

  3. jorgeba wrote:
    > Hi,
    >
    > I have an amazing problem with a double in Java.
    >
    > for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    > Output:
    > 0
    > 0.2
    > 0.399999999 !!!!!!!!!!!
    > 0.6
    > 0.8
    >
    > It is amazing! Does someone understand it?
    >
    > Thank you in advance,
    > Jorge


    The short answer: A computer cannot precisely represent a decimal
    number. Therefore, it is forced to round off all of decimals. The
    0.399999999 here is an example of where it was forced to round off.

    The long answer: Java's default Double.toString(double) (how it converts
    a double to a string) does some voodoo magic that prints out "0.2" when
    the internal representation is equal to what 0.2 would be. Since the
    decimal number has an infinite binary expansion, the computer rounds off
    the number. When it adds 0.2 to that number, the round off (it appears
    to be down here) is accumulated twice and the number is off, I believe,
    by one ulp: the last binary digit in the representation is incorrect
    (guesswork there).

    Whenever one works with floating-point numbers on computers, one should
    always have tolerance guards. A double has 52 bits of significance --
    about 15 to 16 correct significant figures, although the last few may
    have some accumulated round-off error. In a strictfp method/class, all
    arithmetic is done in those 52 bits; otherwise, it may use the
    computer's extended precision if available (Intel uses an 80-bit fp
    number, which should give another dozen or so significant bits).

    To limit the printout of these numbers, one can use:

    System.out.printf("%.5d\n",i); // Java 5+

    which prints the decimal digit to 5 decimal places.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Dec 9, 2007
    #3
  4. jorgeba

    Arne Vajhøj Guest

    jorgeba wrote:
    > I have an amazing problem with a double in Java.
    >
    > for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    > Output:
    > 0
    > 0.2
    > 0.399999999 !!!!!!!!!!!
    > 0.6
    > 0.8
    >
    > It is amazing! Does someone understand it?


    That is how floating point works.

    Floating point is intended for measurements with a bit
    of inaccuracy.

    You may have 0.4 km from your home to your children's school.

    But it is not really wrong to say that there is 0.399999999 km.

    On the other hand if you are doing accounting, then your auditor
    prefer all calculations to be exact.

    Try read an introduction like:
    http://www.lahey.com/float.htm

    Arne
    Arne Vajhøj, Dec 9, 2007
    #4
  5. jorgeba

    Stefan Ram Guest

    jorgeba <> writes:
    >It is amazing! Does someone understand it?


    Finite Sums of Dual fractions, as used by »double«, can not
    represent all decimal fractions precisely. The output
    sometimes is beautified, so that one can not always see this.
    But one can see it in:

    public class Main
    { public static void main( final java.lang.String[] args )
    { java.lang.System.out.println( new java.math.BigDecimal( 0.1 ));
    java.lang.System.out.println( new java.math.BigDecimal( "0.1" )); }}

    0.1000000000000000055511151231257827021181583404541015625
    0.1

    See also

    http://docs.sun.com/source/806-3568/ncg_goldberg.html
    Stefan Ram, Dec 9, 2007
    #5
  6. Joshua Cranmer wrote:
    > A double has 52 bits of significance --

    Normalised doubles have 53 bit mantissas. The first bit is always one so
    they don't bother to store it.
    Mark Thornton, Dec 9, 2007
    #6
  7. jorgeba wrote:
    > Hi,
    >
    > I have an amazing problem with a double in Java.
    >
    > for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    > Output:
    > 0
    > 0.2
    > 0.399999999 !!!!!!!!!!!
    > 0.6
    > 0.8
    >
    > It is amazing! Does someone understand it?


    It is indeed amazing. When I run a program containing your code:

    public class DoubleRounding {
    public static void main(String[] args) {
    for (double i = 0; i<1; i=i+0.2)
    System.out.println (i);
    }
    }

    I get:

    0.0
    0.2
    0.4
    0.6000000000000001
    0.8

    which has only the degree of rounding error I would expect from double.

    0.399999999, as the result of two additions of 0.2, would imply much
    bigger rounding errors than you should get with double.

    Are you sure the output came from exactly the code you posted?

    Patricia
    Patricia Shanahan, Dec 9, 2007
    #7
  8. jorgeba

    Michael Jung Guest

    jorgeba <> writes:
    > I have an amazing problem with a double in Java.
    >
    > for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    > Output:
    > 0
    > 0.2
    > 0.399999999 !!!!!!!!!!!
    > 0.6
    > 0.8
    >
    > It is amazing! Does someone understand it?


    You have to realize that 0.2 (and most of its multiples) are not
    machine (JVM) numbers in that there are represented as is. In fact,
    you can construct examples like .2 + .2 != .4 in Java due to this
    (this concrete example might not work, but something along the lines
    can be constructed).

    Printing such numbers is therefore not as trivial as it seems. See
    the javadoc description of Double.toString to see how it is solved.
    By carefully calculating the steps mentioned, you will recover your
    output. That doesn't make it intuitive, though:)

    Basically, .399999999 represents .2+.2 (whatever they represent in
    java code...) when printed, while .4 represents another number close
    by when printed.

    Michael
    Michael Jung, Dec 9, 2007
    #8
  9. Joshua Cranmer wrote:
    > jorgeba wrote:
    >> Hi,
    >>
    >> I have an amazing problem with a double in Java.
    >>
    >> for (double i = 0; i<1; i=i+0.2)
    >> System.out.println (i);
    >>
    >> Output:
    >> 0
    >> 0.2
    >> 0.399999999 !!!!!!!!!!!
    >> 0.6
    >> 0.8
    >>
    >> It is amazing! Does someone understand it?
    >>
    >> Thank you in advance,
    >> Jorge

    >
    > The short answer: A computer cannot precisely represent a decimal
    > number. Therefore, it is forced to round off all of decimals. The
    > 0.399999999 here is an example of where it was forced to round off.
    >
    > The long answer: Java's default Double.toString(double) (how it converts
    > a double to a string) does some voodoo magic that prints out "0.2" when
    > the internal representation is equal to what 0.2 would be. Since the
    > decimal number has an infinite binary expansion, the computer rounds off
    > the number. When it adds 0.2 to that number, the round off (it appears
    > to be down here) is accumulated twice and the number is off, I believe,
    > by one ulp: the last binary digit in the representation is incorrect
    > (guesswork there).


    I still don't see how to get 0.399999999 from adding 0 + 0.2 + 0.2.

    The double representation of 0.2 has at most half a unit least place
    (ulp) of rounding error. Adding 0 to a number does not change it, so
    that cannot increase the rounding error. Similarly, adding a number to
    itself doubles it, which involves only a change in the exponent, not the
    mantissa.

    Given all that, I would expect at most the smallest possible rounding
    error on conversion of the 0 + 0.2 + 0.2 result back to the shortest
    decimal that rounds to its internal representation. With 53 bits
    effective mantissa, counting the unrepresented bit, and a number whose
    absolute magnitude is less than one, the rounding error should be less
    than 2**(-53) or about 1e-16. A rounding error in the tenth decimal
    place is over a million times too large.

    Patricia
    Patricia Shanahan, Dec 9, 2007
    #9
  10. Patricia Shanahan wrote:
    > Joshua Cranmer wrote:
    >> jorgeba wrote:
    >>> Hi,
    >>>
    >>> I have an amazing problem with a double in Java.
    >>>
    >>> for (double i = 0; i<1; i=i+0.2)
    >>> System.out.println (i);
    >>>
    >>> Output:
    >>> 0
    >>> 0.2
    >>> 0.399999999 !!!!!!!!!!!
    >>> 0.6
    >>> 0.8
    >>>
    >>> It is amazing! Does someone understand it?
    >>>
    >>> Thank you in advance,
    >>> Jorge

    >>
    >> The short answer: A computer cannot precisely represent a decimal
    >> number. Therefore, it is forced to round off all of decimals. The
    >> 0.399999999 here is an example of where it was forced to round off.
    >>
    >> The long answer: Java's default Double.toString(double) (how it
    >> converts a double to a string) does some voodoo magic that prints out
    >> "0.2" when the internal representation is equal to what 0.2 would be.
    >> Since the decimal number has an infinite binary expansion, the
    >> computer rounds off the number. When it adds 0.2 to that number, the
    >> round off (it appears to be down here) is accumulated twice and the
    >> number is off, I believe, by one ulp: the last binary digit in the
    >> representation is incorrect (guesswork there).

    >
    > I still don't see how to get 0.399999999 from adding 0 + 0.2 + 0.2.
    >
    > The double representation of 0.2 has at most half a unit least place
    > (ulp) of rounding error. Adding 0 to a number does not change it, so
    > that cannot increase the rounding error. Similarly, adding a number to
    > itself doubles it, which involves only a change in the exponent, not the
    > mantissa.
    >
    > Given all that, I would expect at most the smallest possible rounding
    > error on conversion of the 0 + 0.2 + 0.2 result back to the shortest
    > decimal that rounds to its internal representation. With 53 bits
    > effective mantissa, counting the unrepresented bit, and a number whose
    > absolute magnitude is less than one, the rounding error should be less
    > than 2**(-53) or about 1e-16. A rounding error in the tenth decimal
    > place is over a million times too large.


    I've thought about this some more, and the answer should be "0.4". The
    nearest double to 0.4 has to have the same mantissa as 0.2, but with
    exponent one greater, the same as the result of 0 + 0.2 + 0.2. No other
    value that rounds to that exponent and mantissa has a shorter decimal
    representation than 0.4, so "0.4" is the correct answer.

    Patricia
    Patricia Shanahan, Dec 9, 2007
    #10
  11. On Sun, 9 Dec 2007 11:10:38 -0800 (PST), jorgeba
    <> wrote:

    >Hi,
    >
    >I have an amazing problem with a double in Java.
    >
    >for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    >Output:
    >0
    >0.2
    >0.399999999 !!!!!!!!!!!
    >0.6
    >0.8
    >
    >It is amazing! Does someone understand it?
    >
    >Thank you in advance,
    >Jorge


    This question comes up entirely too often. Computer arithmetic is
    *not* what you learned in school.

    Please read:

    David Goldberg, "What Every Computer Scientist Should Know About
    Floating-Point Arithmetic"
    http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

    and for more information see

    http://montcs.bloomu.edu/~bobmon/Information/IEEE-754.shtml

    George
    --
    for email reply remove "/" from address
    George Neuner, Dec 10, 2007
    #11
  12. George Neuner wrote:
    > On Sun, 9 Dec 2007 11:10:38 -0800 (PST), jorgeba
    > <> wrote:
    >
    >> Hi,
    >>
    >> I have an amazing problem with a double in Java.
    >>
    >> for (double i = 0; i<1; i=i+0.2)
    >> System.out.println (i);
    >>
    >> Output:
    >> 0
    >> 0.2
    >> 0.399999999 !!!!!!!!!!!
    >> 0.6
    >> 0.8
    >>
    >> It is amazing! Does someone understand it?
    >>
    >> Thank you in advance,
    >> Jorge

    >
    > This question comes up entirely too often. Computer arithmetic is
    > *not* what you learned in school.
    >
    > Please read:
    >
    > David Goldberg, "What Every Computer Scientist Should Know About
    > Floating-Point Arithmetic"
    > http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf
    >
    > and for more information see
    >
    > http://montcs.bloomu.edu/~bobmon/Information/IEEE-754.shtml


    Posters appear to attribute this output to normal rounding error, but
    that does not make sense. The answer in this case should be "0.4", and
    in any case a tenth significant digit error is about a million times too
    large for a single addition of a Java double to a number of the same
    sign and similar magnitude to itself. If that output really came from
    the quoted code, which I doubt, there is something else going on.

    Patricia
    Patricia Shanahan, Dec 10, 2007
    #12
  13. jorgeba

    Eric Sosman Guest

    jorgeba wrote:
    > Hi,
    >
    > I have an amazing problem with a double in Java.
    >
    > for (double i = 0; i<1; i=i+0.2)
    > System.out.println (i);
    >
    > Output:
    > 0
    > 0.2
    > 0.399999999 !!!!!!!!!!!
    > 0.6
    > 0.8
    >
    > It is amazing! Does someone understand it?


    No. I've tried your code on two different Java
    versions on two different processor architectures, and
    I get the same result Patricia Shanahan reports:
    Eric Sosman, Dec 10, 2007
    #13
  14. Eric Sosman wrote:
    > jorgeba wrote:
    >> Hi,
    >>
    >> I have an amazing problem with a double in Java.
    >>
    >> for (double i = 0; i<1; i=i+0.2)
    >> System.out.println (i);
    >>
    >> Output:
    >> 0
    >> 0.2
    >> 0.399999999 !!!!!!!!!!!
    >> 0.6
    >> 0.8
    >>
    >> It is amazing! Does someone understand it?

    >
    > No. I've tried your code on two different Java
    > versions on two different processor architectures, and
    > I get the same result Patricia Shanahan reports:


    I can't think of any Java implementation that I have ever used that
    might be expected to produce that result. Surely no one has implemented
    Java as an Excel macro ;-).
    Mark Thornton, Dec 10, 2007
    #14
  15. jorgeba

    Wayne Guest

    Patricia Shanahan wrote:
    > Patricia Shanahan wrote:
    >> Joshua Cranmer wrote:
    >>> jorgeba wrote:
    >>>> Hi,
    >>>>
    >>>> I have an amazing problem with a double in Java.
    >>>>
    >>>> for (double i = 0; i<1; i=i+0.2)
    >>>> System.out.println (i);
    >>>>
    >>>> Output:
    >>>> 0
    >>>> 0.2
    >>>> 0.399999999 !!!!!!!!!!!
    >>>> 0.6
    >>>> 0.8
    >>>>
    >>>> It is amazing! Does someone understand it?
    >>>>
    >>>> Thank you in advance,
    >>>> Jorge
    >>>
    >>> The short answer: A computer cannot precisely represent a decimal
    >>> number. Therefore, it is forced to round off all of decimals. The
    >>> 0.399999999 here is an example of where it was forced to round off.
    >>>
    >>> The long answer: Java's default Double.toString(double) (how it
    >>> converts a double to a string) does some voodoo magic that prints out
    >>> "0.2" when the internal representation is equal to what 0.2 would be.
    >>> Since the decimal number has an infinite binary expansion, the
    >>> computer rounds off the number. When it adds 0.2 to that number, the
    >>> round off (it appears to be down here) is accumulated twice and the
    >>> number is off, I believe, by one ulp: the last binary digit in the
    >>> representation is incorrect (guesswork there).

    >>
    >> I still don't see how to get 0.399999999 from adding 0 + 0.2 + 0.2.
    >>
    >> The double representation of 0.2 has at most half a unit least place
    >> (ulp) of rounding error. Adding 0 to a number does not change it, so
    >> that cannot increase the rounding error. Similarly, adding a number to
    >> itself doubles it, which involves only a change in the exponent, not the
    >> mantissa.
    >>
    >> Given all that, I would expect at most the smallest possible rounding
    >> error on conversion of the 0 + 0.2 + 0.2 result back to the shortest
    >> decimal that rounds to its internal representation. With 53 bits
    >> effective mantissa, counting the unrepresented bit, and a number whose
    >> absolute magnitude is less than one, the rounding error should be less
    >> than 2**(-53) or about 1e-16. A rounding error in the tenth decimal
    >> place is over a million times too large.

    >
    > I've thought about this some more, and the answer should be "0.4". The
    > nearest double to 0.4 has to have the same mantissa as 0.2, but with
    > exponent one greater, the same as the result of 0 + 0.2 + 0.2. No other
    > value that rounds to that exponent and mantissa has a shorter decimal
    > representation than 0.4, so "0.4" is the correct answer.
    >
    > Patricia
    >


    Perhaps the OP should try using the "strictfrp" modifier on the method?
    Even today, not all hardware is IEEE 754 compliant.

    when I tried it (On "Microsoft Windows XP, Pentium 4") I get:

    ===========Code===========
    public class DblTest {
    public static void main ( String [] args ) {
    for ( double d = 0; d < 1; d=d+0.2 )
    System.out.println( d );
    }
    }
    =========Result===========
    C:\Temp>java DblTest
    0.0
    0.2
    0.4
    0.6000000000000001
    0.8
    ==========================

    (The result is the same using strictfp modifier on main.)

    I've been keeping a list of unexpected "gotchas" for those unfamiliar
    with computer math. See http://www.hccfl.edu/pollock/Java/MathOddities.htm
    for a list of the ones I have. (For no very good reason, this list
    is an applet.)

    -Wayne
    Wayne, Dec 10, 2007
    #15
  16. jorgeba wrote:
    ...
    >I have an amazing problem with a double in Java.


    Only amazing if you are not used to it. ;-)

    >..Does someone understand it?


    (Looking at some of the earlier replies) Apparently.

    Since they have already explained much, I will
    simply add..

    <sscce>
    import java.text.DecimalFormat;

    class NumberTest {
    public static void main(String[] args) {
    DecimalFormat format = new DecimalFormat("0.0");
    for (double i = 0; i<1; i+=0.2) {
    System.out.println (i);
    // get a 'user friendly' representation.
    System.out.println ("Value:\t" + format.format(i));
    }
    }
    }
    </sscce>

    <output>
    0.0
    Value: 0.0
    0.2
    Value: 0.2
    0.4
    Value: 0.4
    0.6000000000000001
    Value: 0.6
    0.8
    Value: 0.8
    </output>

    HTH

    --
    Andrew Thompson
    http://www.physci.org/

    Message posted via http://www.javakb.com
    Andrew Thompson, Dec 11, 2007
    #16
  17. On Mon, 10 Dec 2007 12:32:54 -0800, Patricia Shanahan <>
    wrote:

    >George Neuner wrote:
    >> On Sun, 9 Dec 2007 11:10:38 -0800 (PST), jorgeba
    >> <> wrote:
    >>
    >>> Hi,
    >>>
    >>> I have an amazing problem with a double in Java.
    >>>
    >>> for (double i = 0; i<1; i=i+0.2)
    >>> System.out.println (i);
    >>>
    >>> Output:
    >>> 0
    >>> 0.2
    >>> 0.399999999 !!!!!!!!!!!
    >>> 0.6
    >>> 0.8
    >>>
    >>> It is amazing! Does someone understand it?
    >>>
    >>> Thank you in advance,
    >>> Jorge

    >>
    >> This question comes up entirely too often. Computer arithmetic is
    >> *not* what you learned in school.
    >>
    >> Please read:
    >>
    >> David Goldberg, "What Every Computer Scientist Should Know About
    >> Floating-Point Arithmetic"
    >> http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf
    >>
    >> and for more information see
    >>
    >> http://montcs.bloomu.edu/~bobmon/Information/IEEE-754.shtml

    >
    >Posters appear to attribute this output to normal rounding error, but
    >that does not make sense. The answer in this case should be "0.4", and
    >in any case a tenth significant digit error is about a million times too
    >large for a single addition of a Java double to a number of the same
    >sign and similar magnitude to itself. If that output really came from
    >the quoted code, which I doubt, there is something else going on.
    >
    >Patricia


    The issue is two-fold: whether the fraction has a finite base 2
    representation, and whether the fraction will fit within the
    significand of the floating point number. If either condition is
    false, the number is inexact.

    0.4 is not stored as a 4 with a scale factor, it is stored as the
    binary fraction: 0/2 + 1/4 + 1/8 + 0/16 + 0/32 + 1/64 + ... with the
    leading zero contributors removed by scaling.

    Neither 0.4 nor 0.2 have finite representations which fit into the
    significand of the IEEE double format.

    I'm not sure exactly why the OP is getting 0.399999 when he prints.
    AFAICT, the actual value of the double should be 0.40000000000000002.
    It should print as 0.4.

    George
    --
    for email reply remove "/" from address
    George Neuner, Dec 11, 2007
    #17
  18. Patricia Shanahan wrote:
    > Patricia Shanahan wrote:
    >> Joshua Cranmer wrote:
    >>> jorgeba wrote:
    >>>> Hi,
    >>>>
    >>>> I have an amazing problem with a double in Java.
    >>>>
    >>>> for (double i = 0; i<1; i=i+0.2)
    >>>> System.out.println (i);
    >>>>
    >>>> Output:
    >>>> 0
    >>>> 0.2
    >>>> 0.399999999 !!!!!!!!!!!
    >>>> 0.6
    >>>> 0.8
    >>>>
    >>>> It is amazing! Does someone understand it?
    >>>>
    >>>> Thank you in advance,
    >>>> Jorge
    >>>
    >>> The short answer: A computer cannot precisely represent a decimal
    >>> number. Therefore, it is forced to round off all of decimals. The
    >>> 0.399999999 here is an example of where it was forced to round off.
    >>>
    >>> The long answer: Java's default Double.toString(double) (how it
    >>> converts a double to a string) does some voodoo magic that prints out
    >>> "0.2" when the internal representation is equal to what 0.2 would be.
    >>> Since the decimal number has an infinite binary expansion, the
    >>> computer rounds off the number. When it adds 0.2 to that number, the
    >>> round off (it appears to be down here) is accumulated twice and the
    >>> number is off, I believe, by one ulp: the last binary digit in the
    >>> representation is incorrect (guesswork there).

    >>
    >> I still don't see how to get 0.399999999 from adding 0 + 0.2 + 0.2.
    >>
    >> The double representation of 0.2 has at most half a unit least place
    >> (ulp) of rounding error. Adding 0 to a number does not change it, so
    >> that cannot increase the rounding error. Similarly, adding a number to
    >> itself doubles it, which involves only a change in the exponent, not the
    >> mantissa.
    >>
    >> Given all that, I would expect at most the smallest possible rounding
    >> error on conversion of the 0 + 0.2 + 0.2 result back to the shortest
    >> decimal that rounds to its internal representation. With 53 bits
    >> effective mantissa, counting the unrepresented bit, and a number whose
    >> absolute magnitude is less than one, the rounding error should be less
    >> than 2**(-53) or about 1e-16. A rounding error in the tenth decimal
    >> place is over a million times too large.

    >
    > I've thought about this some more, and the answer should be "0.4". The
    > nearest double to 0.4 has to have the same mantissa as 0.2, but with
    > exponent one greater, the same as the result of 0 + 0.2 + 0.2. No other
    > value that rounds to that exponent and mantissa has a shorter decimal
    > representation than 0.4, so "0.4" is the correct answer.


    Wait a minute. Didn't Java used to have a stupid print(double) and/or
    Double.toString() that gave far fewer decimal digits than it ought to?
    Didn't that get changed at some point, like 1.2 or 1.3?
    --
    John W. Kennedy
    "When a man contemplates forcing his own convictions down another man's
    throat, he is contemplating both an unchristian act and an act of
    treason to the United States."
    -- Joy Davidman, "Smoke on the Mountain"
    John W. Kennedy, Dec 11, 2007
    #18
  19. George Neuner wrote:
    > On Mon, 10 Dec 2007 12:32:54 -0800, Patricia Shanahan <>
    > wrote:
    >
    >
    >>George Neuner wrote:
    >>
    >>>On Sun, 9 Dec 2007 11:10:38 -0800 (PST), jorgeba
    >>><> wrote:
    >>>
    >>>
    >>>>Hi,
    >>>>
    >>>>I have an amazing problem with a double in Java.
    >>>>
    >>>>for (double i = 0; i<1; i=i+0.2)
    >>>> System.out.println (i);
    >>>>
    >>>>Output:
    >>>>0
    >>>>0.2
    >>>>0.399999999 !!!!!!!!!!!
    >>>>0.6
    >>>>0.8
    >>>>
    >>>>It is amazing! Does someone understand it?
    >>>>
    >>>>Thank you in advance,
    >>>>Jorge
    >>>
    >>>This question comes up entirely too often. Computer arithmetic is
    >>>*not* what you learned in school.
    >>>
    >>>Please read:
    >>>
    >>>David Goldberg, "What Every Computer Scientist Should Know About
    >>>Floating-Point Arithmetic"
    >>>http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf
    >>>
    >>>and for more information see
    >>>
    >>>http://montcs.bloomu.edu/~bobmon/Information/IEEE-754.shtml

    >>
    >>Posters appear to attribute this output to normal rounding error, but
    >>that does not make sense. The answer in this case should be "0.4", and
    >>in any case a tenth significant digit error is about a million times too
    >>large for a single addition of a Java double to a number of the same
    >>sign and similar magnitude to itself. If that output really came from
    >>the quoted code, which I doubt, there is something else going on.
    >>
    >>Patricia

    >
    >
    > The issue is two-fold: whether the fraction has a finite base 2
    > representation, and whether the fraction will fit within the
    > significand of the floating point number. If either condition is
    > false, the number is inexact.
    >
    > 0.4 is not stored as a 4 with a scale factor, it is stored as the
    > binary fraction: 0/2 + 1/4 + 1/8 + 0/16 + 0/32 + 1/64 + ... with the
    > leading zero contributors removed by scaling.
    >
    > Neither 0.4 nor 0.2 have finite representations which fit into the
    > significand of the IEEE double format.
    >
    > I'm not sure exactly why the OP is getting 0.399999 when he prints.
    > AFAICT, the actual value of the double should be 0.40000000000000002.
    > It should print as 0.4.

    ....

    We certainly agree on the bottom line, that the final String answer
    should be "0.4". I am confused about whether you are agreeing or
    disagreeing with my analysis leading to that conclusion. Could you clarify?

    Patricia
    Patricia Shanahan, Dec 11, 2007
    #19
  20. George Neuner wrote:
    ....
    > I'm not sure exactly why the OP is getting 0.399999 when he prints.
    > AFAICT, the actual value of the double should be 0.40000000000000002.


    I get 0.40000000000000002220446049250313080847263336181640625

    Patricia
    Patricia Shanahan, Dec 11, 2007
    #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. Web learner

    from List <double> to double[]

    Web learner, Apr 25, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    466
  2. sb
    Replies:
    4
    Views:
    297
    Alberto Barbati
    Feb 19, 2004
  3. Jacek Dziedzic
    Replies:
    5
    Views:
    372
    Old Wolf
    Apr 8, 2004
  4. ferran
    Replies:
    9
    Views:
    3,012
    Kevin Goodsell
    Apr 12, 2004
  5. Sydex
    Replies:
    12
    Views:
    6,454
    Victor Bazarov
    Feb 17, 2005
Loading...

Share This Page