Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why 0.1 represented in float correctly? (I know why not in result of 2.0-1.9)

I've read a lot about float representation recently (including this: How To Represent 0.1 In Floating Point Arithmetic And Decimal). Now I understand that 0.1 can't be represented correctly, and when I do this:

System.out.println(2.0f - 1.9f);

I'll never get precise result.

So the question is: How represented 0.1f in the following code in order to print 0.1 correctly? Is that some kind of syntatic sugar? In the article that I above mentioned says: 0.1 represented in memory as 0.100000001490116119384765625. So why I don't get this output for this code:

System.out.println(0.1f);

How does Java deal with this?

like image 299
Balazs Varhegyi Avatar asked Aug 26 '12 08:08

Balazs Varhegyi


2 Answers

System.out.println performs some rounding for floats and doubles. It uses Float.toString(), which itself (in the oraclew JDK) delegates to the FloatingDecimal class - you can have a look at the source of FloatingDecimal#toJavaFormatString() for gory details.

If you try:

BigDecimal bd = new BigDecimal(0.1f);
System.out.println(bd);

You will see the real value of 0.1f: 0.100000001490116119384765625.

like image 122
assylias Avatar answered Oct 12 '22 23:10

assylias


From the docs for Float.toString(float) (which will always give the same results as the string you're printing):

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.

As 0.1f is the closest representable float to the exact value 0.1, it makes sense that no more digits are required to uniquely distinguish that from any other value of the float type.

like image 44
Jon Skeet Avatar answered Oct 12 '22 23:10

Jon Skeet