Search code examples
javacastingint

Bijection between Java float and integer keeping order


Both int and float in Java are 32 bits size values. Is it possible to program a pair of functions

int toInt(float f);
float toFloat(int n);

such that if f1 and f2 are arbitrary float non-NaN values and i1 and i2 are arbitraty int values:

  • f1 < f2 if and only if toInt(f1) < toInt(f2)
  • f1 > f2 if and only if toInt(f1) > toInt(f2)
  • f1 == f2 if and only if toInt(f1) == toInt(f2)
  • toInt(toFloat(i1) == i1
  • toFloat(toInt(f1)) == f1

Edit: I have edited the question to exclude NaN values for float, thanks to the answers clarifying what happens with those.


Solution

  • Yes. IEEE floats and doubles are arranged in such a way that you can compare them by doing an unsigned comparison of the raw binary representation. The function to convert from float to raw integer and back are java.lang.Float.floatToIntBits and java.lang.Float.intBitsToFloat. These functions are processor intrinsics, so they have an extremely low cost.

    The same is true for longs and doubles. Here the conversion functions are java.lang.Double.doubleToLongBits and java.lang.Double.longBitsToDouble.

    Note that if you want to use the normal signed comparison for your integers, you have to do some additional transformation in addition to the conversion to integer.

    The only exception to this rule is NaN, which does not permit a total ordering anyway.