"""Proof: the two riddles. 0.1 + 0.2 is not 0.3 because 0.1 and 0.2
do not exist in binary; the sum of the two nearest citizens is not
the nearest citizen to 0.3. And at 1e8, float32's local step is 8,
so adding 1 moves nothing."""
from fractions import Fraction
import struct, torch

# the exact value a float64 stores for 0.1
exact = Fraction(struct.unpack("<q", struct.pack("<d", 0.1))[0] & ((1<<52)-1) | (1<<52), 1)
# simpler and fully honest: print the stored values to 30 digits
print(f"stored 0.1  = {0.1:.30f}")
print(f"stored 0.2  = {0.2:.30f}")
print(f"stored sum  = {0.1 + 0.2:.30f}")
print(f"stored 0.3  = {0.3:.30f}")
print(f"0.1 + 0.2 == 0.3 : {0.1 + 0.2 == 0.3}")
print()
t = torch.tensor(1e8, dtype=torch.float32)
print(f"float32: 1e8 + 1 - 1e8 = {((t + 1) - t).item()}")
print(f"the local step at 1e8  = {torch.nextafter(t, torch.tensor(2e8)).item() - t.item()}")
