Floating-Point Representation
Computers store real numbers as a sign, a fractional mantissa, and an exponent, trading exact range for finite precision.
Storing real numbers in finite bits
A computer cannot store an arbitrary real number exactly. Floating-point representation approximates a number as sign x mantissa x base^exponent. The IEEE 754 standard is nearly universal: a double-precision (64-bit) value uses 1 sign bit, 11 exponent bits, and 52 fraction bits, giving roughly 15 to 16 significant decimal digits.
The mantissa is normalized so its leading bit is 1 for base 2, which need not be stored (the implicit bit). The exponent is stored with a bias (1023 for double precision) so that both very large and very small magnitudes are representable. Single precision (32-bit) uses 8 exponent and 23 fraction bits, roughly 7 decimal digits.
Special values
IEEE 754 reserves patterns for positive and negative infinity, produced by overflow or division by zero, and NaN (not a number), produced by 0/0 or sqrt of a negative. Zero has a signed representation. Subnormal numbers fill the gap between the smallest normalized value and zero, providing gradual underflow.
Why some decimals are inexact
Numbers with a finite decimal expansion may have an infinite binary expansion. The value 0.1 is not exactly representable in binary, so 0.1 + 0.2 does not equal 0.3 exactly. This is not a bug but a direct consequence of finite storage in base 2.
import numpy as np
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
print(np.finfo(np.float64).eps) # ~2.22e-16
Design and simulation work, such as the plasma equilibrium and transport models behind the breeder Hyperion, runs almost entirely in double precision because accumulated rounding over millions of operations must stay well below physical tolerances.