Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does casting to float produce correct result in java?

Tags:

java

precision

System.out.println(2.00-1.10)

and

System.out.println((double)(2.00-1.10)) 

both output same result 0.8999999999999999, but

System.out.println((float)(2.00-1.10)) 

outputs 0.9.

Perhaps by default Java performs calculations in double, then why does downcasting corrects result?

And if 1.1 is converted to 1.100000000000001 in double then why does

System.out.println((double)(1.10)) outputs 1.1 only.

EDIT: To get why this happens we need to understand both answers. First the canonical representation is actually different at lower level. Next how the return value of toString is changed/rounded off/matched with the nearest double of argument.

like image 497
Sparsh Singhal Avatar asked May 30 '17 14:05

Sparsh Singhal


People also ask

Can we add float with double without typecasting in Java?

So in Java by default 2.1 is a double type. Now to convert double to float you need to cast while assigning double data to double type cast is not required.

Can we assign long to float in Java?

Long class has the following methods for converting long type value to other primitive types. byte byteValue() returns the value of this Long as a byte. double doubleValue() returns the value of this Long as a double. float floatValue() returns the value of this Long as a float.

Can we convert double to float in Java?

The floatValue() method returns the double value converted to type float .

Can long be assigned to float?

float data type variable can be assigned with any long literal values and it won't result in an error. Long literal values when assigned to the float data type variable, will be converted from the long type value to the floating-point value by Java before assigning.


1 Answers

0.9 is not representable as a double or a float. The internal details of floating point calculation has been answered in various posts on SO, such as: Is floating point math broken?.

In your specific example, you can see the double and float that are closest to 0.9 with this code:

System.out.println(new BigDecimal(0.9d));
System.out.println(new BigDecimal(0.9f));

which outputs the canonical double and float representations of 0.9:

0.90000000000000002220446049250313080847263336181640625
0.89999997615814208984375

Now when you calculate 2.0 - 1.1, the result is:

System.out.println(new BigDecimal(2.0-1.1));

0.899999999999999911182158029987476766109466552734375

You can see that it is not the canonical representation of 0.9 hence you get a different result.

However float precision is not as good and:

System.out.println(new BigDecimal((float) (2.0-1.1)));

0.89999997615814208984375

returns the same number as the canonical representation of 0.9f.

like image 90
assylias Avatar answered Nov 14 '22 23:11

assylias