Density of Floating Point Numbers¶
This notebook enumerates all possible floating point nubmers in a floating point system and shows them in a plot to illustrate their density.
In [1]:
import matplotlib.pyplot as pt
import numpy as np
In [2]:
significand_bits = 4
exponent_min = -3
exponent_max = 4
fp_numbers = []
for exp in range(exponent_min, exponent_max+1):
for sbits in range(0, 2**significand_bits):
significand = 1 + sbits/2**significand_bits
fp_numbers.append(significand * 2**exp)
fp_numbers = np.array(fp_numbers)
print(fp_numbers)
pt.plot(fp_numbers, np.ones_like(fp_numbers), "+")
#pt.semilogx(fp_numbers, np.ones_like(fp_numbers), "+")
[ 0.125 0.1328125 0.140625 0.1484375 0.15625 0.1640625 0.171875 0.1796875 0.1875 0.1953125 0.203125 0.2109375 0.21875 0.2265625 0.234375 0.2421875 0.25 0.265625 0.28125 0.296875 0.3125 0.328125 0.34375 0.359375 0.375 0.390625 0.40625 0.421875 0.4375 0.453125 0.46875 0.484375 0.5 0.53125 0.5625 0.59375 0.625 0.65625 0.6875 0.71875 0.75 0.78125 0.8125 0.84375 0.875 0.90625 0.9375 0.96875 1. 1.0625 1.125 1.1875 1.25 1.3125 1.375 1.4375 1.5 1.5625 1.625 1.6875 1.75 1.8125 1.875 1.9375 2. 2.125 2.25 2.375 2.5 2.625 2.75 2.875 3. 3.125 3.25 3.375 3.5 3.625 3.75 3.875 4. 4.25 4.5 4.75 5. 5.25 5.5 5.75 6. 6.25 6.5 6.75 7. 7.25 7.5 7.75 8. 8.5 9. 9.5 10. 10.5 11. 11.5 12. 12.5 13. 13.5 14. 14.5 15. 15.5 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. ]
Out[2]:
[<matplotlib.lines.Line2D at 0x7fcb7872a790>]
Relative gap size between consecutive floating point numbers. Notice that the maximum is achieved at $1$.
In [3]:
pt.plot(
np.abs(fp_numbers[1:]-fp_numbers[:-1])
/ np.abs(fp_numbers[:-1]))
n_one = int(np.argwhere(np.abs(fp_numbers-1) < 1e-12))
pt.plot([n_one], np.abs(fp_numbers[n_one+1] - fp_numbers[n_one]), 'r*')
Out[3]:
[<matplotlib.lines.Line2D at 0x7fcb7862bac0>]
What about subnormals?¶
In [4]:
subnormals = []
exp = exponent_min
for sbits in range(0, 2**significand_bits):
significand = sbits / 2**significand_bits
subnormals.append(significand * 2**exp)
subnormals = np.array(subnormals)
print(subnormals)
pt.plot(subnormals, np.ones_like(subnormals), "+")
[0. 0.0078125 0.015625 0.0234375 0.03125 0.0390625 0.046875 0.0546875 0.0625 0.0703125 0.078125 0.0859375 0.09375 0.1015625 0.109375 0.1171875]
Out[4]:
[<matplotlib.lines.Line2D at 0x7fcb7861e910>]
In [5]:
fnws = np.concatenate([subnormals, fp_numbers])
pt.plot(np.abs(fnws[1:]-fnws[:-1])/np.abs(fnws[:-1]))
pt.axvline(x=len(subnormals), color='r', linestyle='--')
/tmp/ipykernel_64778/473821165.py:3: RuntimeWarning: divide by zero encountered in true_divide pt.plot(np.abs(fnws[1:]-fnws[:-1])/np.abs(fnws[:-1]))
Out[5]:
<matplotlib.lines.Line2D at 0x7fcb785ccca0>
In [ ]: