Reputation: 11062
Why is there a discrepancy in the display of the following value?
double x = (double)988530483551494912L;
System.out.printf("%f%n", x); -> 988530483551494910.000000
System.out.println(Double.toString(x)); -> 9.8853048355149491E17
System.out.println(new BigDecimal(x)); -> 988530483551494912
As you can see, both toString()
and the %f
conversion lose the precision of the last digit. However, we can see that the last digit is actually precise, because the BigDecimal
conversion preserves it.
Upvotes: 3
Views: 332
Reputation: 11062
Thanks to @user16320675's comment, I'm answering my own question. The reason is that the number 988530483551494912L
has precision beyond the limit of the double
type's precision, and Double.toString()
(and similarly %f
) will, as per documentation, only use the minimum number of significant digits required to distinguish a double
number from adjacent numbers. Adjacent numbers are those that have the smallest representable difference from the original, on either side of it.
This can be demonstrated using Math.nextAfter
to show the adjacent numbers:
import static java.lang.Math.nextAfter;
double x = (double)988530483551494912;
System.out.println(nextAfter(x, Double.MIN_VALUE)); ==> 9.8853048355149478E17
System.out.println(x); ==> 9.8853048355149491E17
System.out.println(nextAfter(x, Double.MAX_VALUE)); ==> 9.8853048355149504E17
So, as we can see, there is no point in adding any more significant figures because this string representation already has enough digits to distinguish the number from adjacent values.
However, a question still remains: it shows 17 significant figures, but 16 would be sufficient. I'm not sure why it issues an extra final digit.
Upvotes: 1