Moonlit
Moonlit

Reputation: 5409

Convert 32 bit fixed point value

In my Java application I need to interpret a 32 Bit Fixed Point value. The number format is as follows: The first 15 bits describe the places before the comma/point, the 16th bit represents the sign of the value and the following 16 bits describe the decimal places (1/2,1/4,1/8,1/16,...).

The input is a byte array with four values. The order of the bits in the byte array is little endian.

How can I convert such a number into Java float ?

Upvotes: 3

Views: 2210

Answers (1)

user555045
user555045

Reputation: 64903

Just do exactly what it says. Assume x is the 32bit fixed point number as int.

So, put the bits after the point, after the point, and don't use the sign here:

float f = (float)(x & 0x7fff_ffff) / (float)(1 << 16);

Put back the sign:

return x < 0 ? -f : f;

You will lose some precision. A float does not have 31 bits of precision, but your input does. It's easily adapted to doubles though.


Since the sign bit is apparently really in the middle, first get it out:

int sign = x & (1 << 16);

Join the two runs of non-sign bits:

x = (x & 0xFFFF) | ((x >> 1) & 0x7fff0000);

Then do more or less the old thing:

float f = (float)x / (float)(1 << 16);
return sign == 0 ? f : -f;

In case your input is little endian format, use the following approach to generate x:

int x = ByteBuffer.wrap(weirdFixedPoint).order(ByteOrder.LITTLE_ENDIAN).getInt();

where weirdFixedPoint is the byte array containing the 32 bit binary representation.

Upvotes: 7

Related Questions