"""Proof: the two classic accidents. Absorption: below half the
local step, an addend vanishes. Cancellation: subtracting two close
numbers deletes their shared leading digits and promotes the noise."""
import torch
t = torch.tensor(1e8, dtype=torch.float32)
print(f"float32 step at 1e8      : {(torch.nextafter(t, t*2) - t).item()}")
print(f"1e8 + 1                  : {(t + 1).item():.1f}   (absorbed)")
print(f"1e8 + 5                  : {(t + 5).item():.1f}   (rounds up: past half the step)")
a = torch.tensor(1.0000001, dtype=torch.float32)
b = torch.tensor(1.0000000, dtype=torch.float32)
d = (a - b).item()
print(f"\n(1.0000001 - 1.0) in float32 = {d:.10e}")
print(f"true answer                  = 1.0000000e-07")
print(f"relative error               = {abs(d - 1e-7)/1e-7:.1%}")
print("seven leading digits matched and left; only the rounding")
print("noise of the inputs remained.")
