IEEE-754 Floating Point
IEEE-754 stores real numbers in binary scientific notation with a sign, exponent, and fraction.
The format
An IEEE-754 number is sign × 1.fraction × 2^exponent. A 32-bit float uses 1 sign bit, 8 exponent bits, and 23 fraction bits; a 64-bit double uses 1, 11, and 52. The leading 1 is implicit for normal numbers, giving one free bit of precision.
The bias
The exponent is stored with a bias — 127 for single precision, 1023 for double — so it can represent both positive and negative exponents without a separate sign. A stored 128 means an actual exponent of 1.
Precision
Single precision gives about 7 decimal significant digits, double about 15 to 16. Because the fraction has fixed width, the gap between representable numbers grows with magnitude; precision is relative, not absolute.
Special encodings
Reserved exponent patterns encode positive and negative infinity, quiet and signaling NaN, signed zeros, and subnormal numbers that fill the gap near zero. These let computations continue meaningfully past overflow and underflow.
Why 0.1 is not exact
One tenth has no finite binary fraction, so it is stored as the nearest representable value. Summing such approximations produces the familiar small errors, which is why floats should rarely be compared for exact equality.
Simulation note
Physics codes for designs like the Hyperion breeder rely on double precision to keep rounding error far below modeling uncertainty across long time-stepped runs.
import struct
bits = struct.unpack('>I', struct.pack('>f', 0.1))[0]
print(f'{bits:032b}') # single-precision layout of 0.1