Home > Software engineering >  Java int cast to float cast to int does not equal original int
Java int cast to float cast to int does not equal original int

Time:09-28

Using this snippet:

    public static void main(String[] args){
        int i = XXX;
        System.out.println( (int) ( (float) i ) );
    }

If int i = 1234; then the output is 1234

If int i = Integer.MAX_VALUE; then the output is equal to Integer.MAX_VALUE

However, if int i = 1234567990;, then the output is 1234567936, which is not equal to i.

And if int i = 1235567990;, then the output is 1235568000, which is also not equal to i.

How does this casting conversion math work?

CodePudding user response:

This is entirely normal for floating point maths. Both int and float are 32-bit values. float only has about 7 significant digits of precision, because it uses some of the bits for scale. As you get to large values, "adjacent" float values (i.e. going from one precisely-representable value to the next one up) are more than 1 apart - so any integer between those two adjacent values can't be represented precisely as a float.

Another way of looking at this is a version of the pigeonhole principle:

  • Both float and int have 2^32 possible bit patterns
  • There's a valid mapping from every int to a float value
  • Every bit pattern is a valid int, so there are 2^32 possible integer values
  • float also contains the value 1.5 (and many other non-integers, but we only need one of them to prove the point)
  • Therefore at least two int values must map to the same float, which means the mapping cannot be reversible in every case

Note that if you use double, you're fine - every int can be cast to double and then cast back to int, and you'll get the original value. However, using double and long (instead of int) you get the same problem, for the same reason, but using 64 bits instead of 32.

CodePudding user response:

How does this casting conversion math work?

Casting an int to a float works the same way any float operation works: Do the math (which in this case is nothing - just take the int as is), then convert it to the 'nearest representable float' - that float which is closer to the result of the calculation than any other.

Why is it 'lossy'? See the other answer.

What's the math behind which floats are representable? Wikipedia's page on IEEE754 floating point representation explains that.

  • Related