float to double giving Strange results

I came across with this behavior of float and double during type casting.

I modified my actual statements to better understanding.

1

System.out.println((double)((float)(128.12301)));//Output:128.12301635712188

Same output all the time.

2

System.out.println((double)((float)(128888.12301)));//Output:128888.125

Both outputs are strange for me I can't understand how it's working.

Can anyone help me out?

Jon Skeet
people
quotationmark

There are several steps involved here, each with different numbers. Let's split the code up for each statement:

double original = 128.12301; // Or 128888.12301
float floatValue = (float) original;
double backToDouble = (double) floatValue;
System.out.println(backToDouble);

So for each number, the steps are:

  1. Compile time: Convert the decimal value in the source code into the nearest exact double value
  2. Execution time: Convert the double value to the nearest exact float value
  3. Execution time: Convert the float value into a double value (this never loses any information)
  4. Execution time: Convert the final double value into a string

Steps 1 and 2 can lose information; step 4 doesn't always print the exact value - it just follows what Double.toString(double) does.

So let's take 128.12301 as an example. That's converted at compile-time to exactly 128.123009999999993624442140571773052215576171875. Then the conversion to float yields exactly 128.123016357421875. So after the conversion back to double (which preserves the value) we print out 128.123016357421875. That prints 128.12301635712188 because that's the fewest digits in can print out without being ambiguous between that value and the nearest double value greater than or less than it.

Now with 128888.12301, the exact double value is 128888.123009999995701946318149566650390625 - and the closest float to that is exactly 128888.125. After converting that back to a double, the exact value of that double is printed out because there are other exact double values near it.

Basically, the result will depend on how many significant digits you've included to start with, and how much information is lost when it rounds to the nearest double and then to the nearest float.

people

See more on this question at Stackoverflow