System.out.println(d)
will go through Double.toString
which is a fairly complex method (as seen in its documentation) an will not always behave as you'd expect. It basically gives the shortest string which uniquely determines d
.
Perhaps the output of this program clarifies this:
double[] tests = {
0.49999999999999990d, //output 0.4999999999999999 as expected
0.49999999999999991d, //output 0.4999999999999999
0.49999999999999992d, //output 0.49999999999999994
0.49999999999999993d, //output 0.49999999999999994
0.49999999999999994d, //output 0.49999999999999994 as expected
0.49999999999999995d, //output 0.49999999999999994
0.49999999999999996d, //output 0.49999999999999994
0.49999999999999997d, //output 0.49999999999999994
0.49999999999999998d, //output 0.5
};
String[] literals = {
"0.49999999999999990d",
"0.49999999999999991d",
"0.49999999999999992d",
"0.49999999999999993d",
"0.49999999999999994d",
"0.49999999999999995d",
"0.49999999999999996d",
"0.49999999999999997d",
"0.49999999999999998d",
};
String f = "%-25s%-65s%-25s%n";
System.out.printf(f, "Literal", "Actually represents", "Printed as");
for (int i = 0; i < tests.length; i++)
System.out.printf(f, literals[i],
new BigDecimal(tests[i]).toString(),
Double.valueOf(tests[i]));
Output:
Literal Actually represents Printed as
0.49999999999999990d 0.49999999999999988897769753748434595763683319091796875 0.4999999999999999
0.49999999999999991d 0.49999999999999988897769753748434595763683319091796875 0.4999999999999999
0.49999999999999992d 0.499999999999999944488848768742172978818416595458984375 0.49999999999999994
0.49999999999999993d 0.499999999999999944488848768742172978818416595458984375 0.49999999999999994
0.49999999999999994d 0.499999999999999944488848768742172978818416595458984375 0.49999999999999994
0.49999999999999995d 0.499999999999999944488848768742172978818416595458984375 0.49999999999999994
0.49999999999999996d 0.499999999999999944488848768742172978818416595458984375 0.49999999999999994
0.49999999999999997d 0.499999999999999944488848768742172978818416595458984375 0.49999999999999994
0.49999999999999998d 0.5 0.5
As can be seen, the literal is sometimes far from the value it actually represents, which means that Double.toString
prints something that may look surprising.