Like Java round-trip String & # 8594; float & # 8594; String even for (some) values โ€‹โ€‹not represented as float?

As explained in many places (for example, Why decimal numbers cannot be represented exactly in binary format? ), Not all decimal fractions can be represented as floating point values โ€‹โ€‹(for example, stored in float in Java).

Typical example: "0.2". According to this excellent IEEE 754 Converter , the float closest to 0.2 is approximately 0.20000000298023224, so parsing "0.2" as a float should give this result.

However, I noticed that Java seems 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

Test on IDeone.com

How does Java know that I need the (rounded) output "0.2" instead of the exact output "0.20000000298023224" as described above?

Javadocs Float.toString() try to explain this:

How many digits should be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and besides this, as many, but only as many digits as necessary, it unambiguously distinguishes the value of the argument from adjacent values โ€‹โ€‹such as a float.

Unfortunately, this bothers me even more. Why does "printing as many digits as possible to unambiguously distinguish the value of the argument" allow Java to print "0.2"?

Ideally, the answer also explains why this printing algorithm was chosen. Is it possible to do (some) round trips, as in this example? Is there any other motivation?

+5
source share
2 answers

Output rounding is not associated with any printing algorithm. This is due to the size of the float . If you do:

 String fs = "0.2"; double f = Float.parseFloat(fs); System.out.println(f); 

You are getting:

+0,20000000298023224

Test at Ideone.com

This clearly shows that the string "0.2" is parsed as 0.20000000298023224, but the floating point data type cannot hold it and rounds it to 0.2. double data type is capable of holding this data, and therefore, when you parse it as a float , but store it in a double , you will get the expected result.

+2
source

I believe 0.2 belongs to Value Conversion .

+1
source

All Articles