Each 64-bit floating-point number is broken up into three parts:
- 1 bit is used for the sign (
-
/+
) - 11 bits are used for the exponent
- 52 bits are used for the fraction
Looking at just the exponent portion:
1024 512 256 128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 0 0 0
With 11 bits, we have the range of 0 to 2047, which is a nice wide range, but how do we represent negative exponents? We could use the left-most bit to represent the sign (-
/+
), but biased exponents work differently.
Instead, with biased exponents, we take that full range of numbers, 2047, and integer divide it by two to get a truncated integer value.
2047 // 2 = 1023
This number, 1023, represents the full range of positive exponents we have in our floating point number. The range of negative exponents we have available in our floating-point number will always be one less than the number of positive exponents: -1022, in this case.
So, because of biased exponents, our full exponent range for a given floating-point number is -1022 to 1023.
You might also notice that if we add these two numbers together, we get 2045 and not 2047. As stated on the Wikipedia page for double-precision floating-point format, this is because the value of -1023 and +1024 are "reserved for special numbers."
Take this 11-bit exponent example:
0 1 1 1 1 1 1 1 1 1 1 = 1023
This is the binary value of 1023. As a biased exponent, though, this value is -1022 + 1023, or 1.
If we have this mantissa:
12345
And we apply the biased exponent 01111111111
, then we get the real number:
1.2345
We've shifted our floating point to the right 1 exponent value.