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?
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:
double
valuedouble
value to the nearest exact float
valuefloat
value into a double
value (this never loses any information)double
value into a stringSteps 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
.
See more on this question at Stackoverflow