Skip to content

Uncertainty propagation

Level: 201 · working knowledge

One line: Significant figures compress "how well do I know this?" into a digit count — one number where the honest answer needs two — and this page is what the compression was approximating.

The compression, and what it costs

A significant-figure count is a quantised uncertainty. It can only step by factors of ten, because it can only add or remove whole digits. Reality is not so accommodating.

1.0   written to 2 s.f.  →  ±0.05  →  5.00% relative
9.9   written to 2 s.f.  →  ±0.05  →  0.51% relative

Identical notation, a ten-fold difference in what is actually known. Every value between those two is squeezed into the same "2 s.f." bucket, so the notation is at its most misleading exactly where the leading digit is small.

That is the cost of writing one number. The fix is to write two: a value and its uncertainty.

The real rules

For independent random errors, uncertainties combine in quadrature — squares, not sums:

Operation Combine Which error
a + b, a − b σ = √(σa² + σb²) absolute
a × b, a ÷ b rel = √(ra² + rb²) relative

Two things fall straight out of this table, and both were asserted without proof back on the significant figures page:

  • + and use absolute error, which is why their rule is about decimal places.
  • × and ÷ use relative error, which is why their rule is about significant figures.

The sig-fig rules are not two arbitrary conventions. They are the quadrature formulas, rounded to the nearest digit.

Adding uncertainties linearly instead is the worst case — correct only if the errors are perfectly correlated, which independent measurements are not. It is a defensible safety margin and an indefensible estimate.

What the program prints

Verified output of uncertainty_propagation.py — regenerated by tools/run_examples.py, never hand-typed.

1. SIG FIGS QUANTIZE UNCERTAINTY VERY COARSELY
   Two numbers, both written with 2 significant figures:
      1.0  ->  +/- 0.05  =   5.00% relative
      9.9  ->  +/- 0.05  =   0.51% relative
   Same sig-fig count, a ten-fold difference in what is actually known.
   Sig figs can only step by factors of 10; reality does not.

2. THE REAL RULES
   For independent random errors, add in QUADRATURE (not linearly):
     sum / difference   sigma = sqrt(sa^2 + sb^2)          absolute
     product / quotient  rel  = sqrt(ra^2 + rb^2)          relative
   Linear addition is the worst case -- correct only if the errors
   are perfectly correlated, which independent measurements are not.

3. A RECTANGLE
     side a   12.30 +/- 0.10  (0.81%)
     side b   4.50 +/- 0.10  (2.22%)
     area     55.4 +/- 1.3  (2.37%)
     sig-fig answer:  12.3 x 4.5 -> 2 s.f. -> 55
     Here the two roughly agree: the propagated 55.4 +/- 1.3 and the
     sig-fig '55' make about the same claim. They do not always.

4. WHERE SIG FIGS UNDERSTATE -- ACCUMULATION
   Ten independent measurements, each 1.0 +/- 0.05, added up:
     sig figs   every term known to the 0.1 place, so the sum is too
                -> 10.0          which CLAIMS +/- 0.05
     truth      sigma = sqrt(10) x 0.05 = 0.158
                -> 10.00 +/- 0.16  (1.58%)
     sig figs claims 3.2x more precision than is there.
     Error accumulates; the place-value rule cannot see that it has.

5. WHERE SIG FIGS OVERSTATE -- A LUCKY LAST DIGIT
   One measurement, 1.0 +/- 0.05, squared:
     sig figs   2 s.f. in, 2 s.f. out -> 1.0   which CLAIMS +/- 0.05
     truth      1.000 +/- 0.071  (7.07%)
     the real spread is 1.41x wider than the notation admits.

6. WHAT TO ACTUALLY DO
   Sig figs are fine for a one-step classroom calculation and for
   reporting a single measurement. The moment a value passes through
   several steps, carry the uncertainty explicitly and round ONCE,
   at the end -- rounding at every step is itself a source of error.

Sig figs understate accumulated error

Section 4 above is the case that should change how you read a spreadsheet. Ten measurements, each 1.0 ± 0.05, added together:

  • Sig figs say: every term is known to the tenths place, so the sum is too → 10.0, which claims ±0.05.
  • Quadrature says: σ = √10 × 0.05 = 0.15810.00 ± 0.16.

The notation claims about three times more precision than exists. And the place-value rule structurally cannot see the problem: it looks at the places of the terms, and ten terms have the same places as one. Error accumulates; digit-counting does not accumulate with it.

This is the failure mode that matters in practice, because real calculations are long. Every intermediate rounding is itself a small injection of error, which is why the discipline is: carry full precision through the calculation and round exactly once, at the end. Rounding at each step is not conservative — it is a second error source layered on the first.

Sig figs also overstate

Section 5 runs it the other way. Square a single 1.0 ± 0.05:

  • Sig figs say: two in, two out → 1.0, claiming ±0.05.
  • Quadrature says: 1.000 ± 0.071 — the real spread is √2 wider than the notation admits.

So the compression is not conservative in a predictable direction. It is simply lossy. You cannot patch it with a rule of thumb like "add a digit for safety", because you do not know which way this particular calculation went without doing the propagation that the rule of thumb was meant to avoid.

When each one is right

Use significant figures for a single reported measurement, a one-step calculation, and anywhere a reader needs a number rather than an analysis. They are a good notation and this page is not an argument against them.

Carry uncertainty explicitly as soon as a value passes through several steps, as soon as terms accumulate, and always when a decision depends on whether two results differ. "Is A bigger than B?" is unanswerable from significant figures alone and trivially answerable from A = 55.4 ± 1.3, B = 54.9 ± 1.2.

The honest summary: significant figures are the right tool for reporting and the wrong tool for computing.

Run it yourself

From the root of your clone of this repository:

python3 01_Precision/uncertainty_propagation/examples/uncertainty_propagation.py

See also