jorgeba said:
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.