IEEE 754, binary-32 numbers are specified as follows:
Essentially it has three parts:
- 1 bit
float32_sign
representing sign
- 23 bit
float32_fraction[]
representing binary fraction co-efficients
- 8 bit
float32_exp
represnting an integer exponent of 2
See wikipedia/Single-precision_floating-point_format for details.
The formula to get the actual number is:
Forgetting the exponent, the fraction part can represent pow(2, 23) = 8388608
values accurately. The maximum and minimum values in this range are:
( 1 + 0, 1 + sum(pow(2, -i)) ) # All co-efficients being 0 and 1 resp. in the above formula
=> ( 1, 2 - pow(2, -23) ) # By geometric progression
~> ( 1, 2 ) # Approximation by upper-bound
So for exponent being 1 (float32_exp = 128
), we will have 8388608 numbers between (1,2)
and (-1,-2)
.
However for large numbers such as when exponent is 126 (float32_exp = 253
), we still have only 8388608 numbers to represent the gap between (2^126), 2^127)
and (-2^126, -2^127)
.
A distribution graph between 1 and 128 looks like:
The graph is so steep at 0 that plotting it would make it look like a single value at 0 only. Do note that the graph is a hyperbola.
The formula to get the number of floating point numbers between two values is:
def num_floats(begin, end):
# pow(2, 23) * (log(end, 2) - log(start, 2)) == pow(2, 23) * log(end/start, 2)
return 8388608 * math.log(float(end)/float(begin), 2)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…