Skip to content

Instantly share code, notes, and snippets.

@dhermes
Last active January 13, 2023 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhermes/f9391c0948c89c74e0f29d3805d3314d to your computer and use it in GitHub Desktop.
Save dhermes/f9391c0948c89c74e0f29d3805d3314d to your computer and use it in GitHub Desktop.
[2023-03-13] How many values are nan? (IEEE-754 float64)

How many nan values exist?

It turns out a lot (2**52). Anything where the 12 exponent bits are all 1, independent of the values of the other 52 bits).

$ python main.py
binary(1.0)  = 0011111111110000000000000000000000000000000000000000000000000000
binary(2.0)  = 0100000000000000000000000000000000000000000000000000000000000000
binary(-1.0) = 1011111111110000000000000000000000000000000000000000000000000000
binary(1.5)  = 0011111111111000000000000000000000000000000000000000000000000000
binary(1.75) = 0011111111111100000000000000000000000000000000000000000000000000
binary(nan)  = 0111111111111000000000000000000000000000000000000000000000000000
================================================================================
float(0011111111110000000000000000000000000000000000000000000000000000) = 1.0
float(0111111111111000000000000000000000000000000000000000000000000000) = nan
float(0111111111111100000000000000000000000000000000000000000000000000) = nan
float(0111111111111110000000000000000000000000000000000000000000000000) = nan
float(1111111111111110000000000000000000000000000000000000000000000000) = nan
import struct
# NOTE: We use big-endian because it reads left-to-right, even though most
# systems use little-endian.
FLOAT_FORMAT = ">d"
def as_bits(value):
as_bytes = struct.pack(FLOAT_FORMAT, value)
return "".join([f"{byte_:08b}" for byte_ in as_bytes])
def from_bits(bits64):
as_bytes = bytes([int(bits64[i : i + 8], 2) for i in range(0, 64, 8)])
(value,) = struct.unpack(FLOAT_FORMAT, as_bytes)
return value
def main():
print(f"binary(1.0) = {as_bits(1.0)}")
print(f"binary(2.0) = {as_bits(2.0)}")
print(f"binary(-1.0) = {as_bits(-1.0)}")
print(f"binary(1.5) = {as_bits(1.5)}")
print(f"binary(1.75) = {as_bits(1.75)}")
print(f"binary(nan) = {as_bits(float('nan'))}")
print("=" * 80)
binary1_0 = "0011111111110000000000000000000000000000000000000000000000000000"
print(f"float({binary1_0}) = {from_bits(binary1_0)}")
binary_nan1 = "0111111111111000000000000000000000000000000000000000000000000000"
print(f"float({binary_nan1}) = {from_bits(binary_nan1)}")
binary_nan2 = "0111111111111100000000000000000000000000000000000000000000000000"
print(f"float({binary_nan2}) = {from_bits(binary_nan2)}")
binary_nan3 = "0111111111111110000000000000000000000000000000000000000000000000"
print(f"float({binary_nan3}) = {from_bits(binary_nan3)}")
binary_nan4 = "1111111111111110000000000000000000000000000000000000000000000000"
print(f"float({binary_nan4}) = {from_bits(binary_nan4)}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment