JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Machine Epsilon and Unit Roundoff

Floating-point numbers leave gaps between them, and that gap size has a name. Meet machine epsilon and unit roundoff — the two numbers that tell you exactly how many digits you can trust.

The gaps between the numbers

In the previous guide you saw that a computer stores a real number as a sign, a fixed-length binary significand, and an exponent under the IEEE 754 standard. The crucial consequence is this: only finitely many numbers are representable, so the representable numbers sit on a discrete grid with gaps between them. The key fact about that grid is that it is not evenly spaced — the gaps grow as the numbers grow, because shifting the exponent up by one doubles the spacing.

Picture the numbers between 1 and 2. The significand has a fixed number of bits, so they are spread evenly across that interval. Now look between 2 and 4: the same number of significand patterns must cover an interval twice as wide, so the spacing there is exactly twice as large. Between 4 and 8 it doubles again. The grid is fine near zero and coarse far away — like a ruler whose tick marks spread apart as you read to the right. This is the whole reason floating-point error is best measured relatively, not absolutely.

What machine epsilon actually is

Machine epsilon is the size of the gap right above the number 1. More precisely, it is the distance from 1 to the next larger representable number. If the significand carries p significant bits after the leading 1, then that next number is 1 + 2^(-(p-1)), so machine epsilon equals 2^(-(p-1)). For double precision, which keeps 52 stored significand bits, this is 2^(-52), about 2.22 × 10^(-16). For single precision it is 2^(-23), about 1.19 × 10^(-7).

A handy mental test: machine epsilon is the smallest number eps such that the computer evaluates 1 + eps as something larger than 1. Add anything smaller than half a gap and it rounds straight back down to exactly 1 — the addition vanishes. That is why a loop like `while (1 + x > 1) x = x/2;` halts when x has shrunk to roughly machine epsilon: it is literally feeling for the edge of the grid.

Unit roundoff: the relative-error ceiling

Machine epsilon describes the gap; unit roundoff (written u) describes the worst error you make when you round a real number onto the grid. With round-to-nearest — the default rounding mode in IEEE 754 — any real number x (within range) lands on a grid point no farther than half a gap away. Half a gap, relative to the number, is at most 2^(-p), which is half of machine epsilon. So u = eps/2 = 2^(-53) ≈ 1.11 × 10^(-16) for double precision.

The cleanest way to state this is the rounding model. Let fl(x) mean the floating-point number nearest to x. Then for every x in range, fl(x) = x(1 + delta) with |delta| <= u. Read it out loud: rounding changes a number by a relative amount no bigger than u. That single inequality is the foundation of nearly all of floating-point arithmetic analysis — the relative error of storing a number is bounded by u, full stop.

fl(x)         = x (1 + delta),    |delta| <= u
fl(a op b)    = (a op b)(1 + d),   |d| <= u,   op in { +, -, *, / }

double:  eps = 2^-52 ~ 2.22e-16,   u = eps/2 = 2^-53 ~ 1.11e-16
single:  eps = 2^-23 ~ 1.19e-07,   u = eps/2 = 2^-24 ~ 5.96e-08
The rounding model: storing a number, and each correctly-rounded operation, costs at most a relative u.

The rounded-operation model

IEEE 754 promises something stronger than just storing numbers well: each of the basic operations +, -, *, / (and the square root) is correctly rounded. This means the hardware computes the exact real result of the operation and then rounds that once to the nearest grid point. So for any two stored numbers a and b, the computed result satisfies fl(a op b) = (a op b)(1 + d) with |d| <= u. Every single operation injects at most a relative u of error — no more, no surprises.

This is wonderfully reassuring and also a trap. The reassurance: a single operation is as accurate as the format allows. The trap: errors accumulate across many operations, and worse, a perfectly small rounding error can be amplified by a badly-conditioned step. The classic villain is catastrophic cancellation — subtracting two nearly equal numbers. Each input was rounded with relative error up to u, but subtraction throws away the matching leading digits and leaves only the noisy tail, so the relative error of the difference can balloon far beyond u even though no operation broke its promise.

Why this matters before you compute anything

Unit roundoff is not a footnote — it is the unit in which every later guide measures error. When you later read that an algorithm is backward stable, the precise statement is that it returns the exact answer to a problem whose data has been perturbed by only a small multiple of u. When you read a numerical stability bound, the right-hand side is almost always something times u times a condition number. Knowing u in your head — 10^(-16) for double, 10^(-7) for single — lets you sanity-check a result in seconds.

  1. Decide your format: double precision (u ≈ 1.11 × 10^(-16), ~16 digits) is the default; single (u ≈ 5.96 × 10^(-8), ~7 digits) only when memory or speed truly demands it.
  2. Take u as your starting error budget — the best relative accuracy any result can have before the work even begins.
  3. For each step, ask: is it well-conditioned, or does it amplify error? A condition number of 10^k roughly costs you k digits off your budget.
  4. Sanity-check the final answer's expected accuracy against u: if you expected 10 good digits but the math says you can only keep 4, trust the math and rethink the algorithm.