0

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?

akash
  • 22,664
  • 11
  • 59
  • 87

3 Answers3

3

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

System.out.println(number) will go through Double.toString() which is a fairly complex method (as seen in its documentation) an will not always behave as you'd expect. It basically gives the shortest string which uniquely determines number.

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 double. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument d. Then d must be the double value nearest to x; or if two double values are equally close to x, then d must be one of them and the least significant bit of the significant of d must be 0.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
0

A float is a 32 bit IEEE 754 floating point.

A double is a 64 bit IEEE 754 floating point.

It is the same for float and double, both are binary floating point types, but double has more precision than float.

Check this for more details

Salah
  • 8,567
  • 3
  • 26
  • 43