Search code examples
javaunsigned

Unsigned Integers to Floating Point in Java


How can I convert an unsigned int or long represented as the signed Java equivalents to float or double in Java? I found some hints in the Google Guava libraries (Link), but I do not understand the reasoning behind the implementation. Here is the code fragment that converts an unsigned long stored in value to float:

198  @Override
199  public float floatValue() {
200    @SuppressWarnings("cast")
201    float fValue = (float) (value & UNSIGNED_MASK);
202    if (value < 0) {
203      fValue += 0x1.0p63f;
204    }
205    return fValue;
206  }

As far as I understand, the first check is necessary to check that the value is not negative since the UNSIGNED_MASK is Long.MAX_VALUE. In this case, the conversion matches the Java semantics of long to float conversion. But why is a constant added, if the value is negative?


Solution

  • If you wish to treat to original long value as if it's unsigned, if the signed value is negative, you have to add 2^63 to account for the sign bit.

    If the original value is already positive, you don't have to add anything, since the sign bit is 0, so only the value of the bottom 63 bits should be considered.

    For example, take 1111...111111 (64 1 bits).

    The signed value of this long number is -1.

    However, the unsigned value is 2^63+2^62+...+2^1+2^0.

    (float) (value & UNSIGNED_MASK) will give you the float value of 2^62+2^61+...+2^1+2^0.

    Therefore you have to add 2^63.