No sense in doing it the hard way. They call these floating-point for a reason. Just move the decimal point to convert from binary to decimal.
Example (32-bit):
Hex Value: BDAE147B
Binary Value: 1011 1101 1010 1110 0001 0100 0111 1011
Sign: 1 (Negative)
Exponent: 01111011 = 123 (decimal)
Signficand: 01011100001010001111011 = 3,019,899 (decimal)
-
To process the exponent, subtract the bias of 127. This allows for both positive and negative exponents. 123 - 127 = -4
-
To process the significand, shift the "binary decimal point" the same way you'd do it in decimal. To turn 456 into 45.6, you divide by 10, right? That's a 1 followed by 1 zero; the number of zeroes indicating the number of decimal places to shift.
In this example, we've got 23 bits of sigificand, which means that a binary number with 1 followed by 23 zeroes represents the number of binary digits to shift. The number comes out to 8,388,608 decimal.
PointShifter = 2 ^ SignificandBits
The decimal representation of the significand is 3,019,899. Divide that by 8,388,608 to create 0.36000001430511474609375 or thereabouts. Last, add 1 to that to make 1.36000001430511474609375
-
Use the fomula (-1 ^ Sign) * (2 ^ Exponent) * Significand to get the final value: -0.085000000894069671630859375... Or, as the original number was, -0.085
----------
In 32-bit floats, the exponent field is 8 bits and the bias is 127. In 64-bit floats, the exponent field is 11 bits and the bias is 1,023. The pattern here is that the bias is the halfth value of the total number of representable values by the field. 8 bits makes for 256 values, half of which is 128. Since the first value is 0, the halfth value is 127. Same with 11 bits: 2,048 values, 1,023 bias.
Bias = (2 ^ ExponentBits) / 2 - 1
That said, given the "s10e5" business... 5 bits stores 32 values, which would make the bias 15.
With 10 bits for the significand, the number to use shifting the decimal point is 1,024.
Hex Value: 50DE
Binary Value: 0101 0000 1101 1110
Sign: 0 (Positive)
Exponent: 10100 = 20; 20 - 15 = 5; 2 ^ 5 = 32
Significand: 0011011110 = 222; 222 / 1024 + 1 = 1.216796875
Final value: 38.9375
This value appears to be video-game-ish, since 0.9375 is exactly 15/16.
__________
Edit × 2:
A note on denormalized values... If the exponent field is stored as 0, don't subtract the bias: the number is denormalized. Instead, in this situation, the significand does not have an implicit 1 preceding the decimal point. It's 0.xxx, not 1.xxx. Simply sign the significand in this scanario. |