As explained in many places (such as Why can't decimal numbers be represented exactly in binary?), not all decimal fractions can be represented as floating point values (such as stored in a float
in Java).
The typical example given is "0.2". According to this nifty IEEE 754 Converter, the float
closest to 0.2 is approximately 0.20000000298023224 , so parsing "0.2" as a float
should yield this result.
However, I noted that Java seems to be able to do the impossible:
String number="0.2";
float f = Float.parseFloat(number);
System.out.println("Result of roundtrip String -> float -> String: "+f);
prints:
Result of roundtrip String -> float -> String: 0.2
How does Java know that I wanted the (rounded) output "0.2", instead of the precise output "0.20000000298023224" as explained above?
The Javadocs of Float.toString()
try to explain this:
How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float.
Unfortunately, this confuses me even more. Why does "printing as many digits as needed to uniquely distinguish the argument value" allow Java to print "0.2"?
Ideally, the answer would also explain why this printing algorithm was chosen. It is to make (some) round-trips work, as in this example? Is there another motivation?