MATH-300 · Lesson 1 of 5 · 34 min

Errors and floating point

Almost every number an engineer computes today comes out of a computer: the stresses from a finite element model, the flows in a pipe network, the trajectory of a rocket, the forecast from a reservoir simulator. None of these numbers is exact. Numerical methods are the techniques that turn mathematical problems into arithmetic a computer can do, and the first skill they demand is understanding error: where it comes from, how big it is, and how to keep it from growing until the answer is meaningless.

This chapter sets up the vocabulary for the whole course: absolute and relative error, the sources of error, how computers store real numbers, round-off and truncation error, catastrophic cancellation and conditioning.

Measuring error

If p is the true value and \(\tilde{p}\) an approximation, the absolute error and relative error are

\[E_a = |p - \tilde{p}|, \qquad E_r = \frac{|p - \tilde{p}|}{|p|}\]

Relative error is usually more meaningful. An error of 1 mm is negligible in the span of a bridge and disastrous in the bore of an engine cylinder. A relative error of about \(5 \times 10^{-n}\) corresponds to roughly n correct significant figures.

In practice the true value is unknown, so iterative methods estimate the error from successive approximations, stopping when the approximate relative error falls below a tolerance:

\[\varepsilon_a = \left|\frac{x_{\text{new}} - x_{\text{old}}}{x_{\text{new}}}\right| < \varepsilon_s\]

Worked problem

Measuring g

A student measures g = 9.78 m/s² against the accepted 9.81 m/s². Find the absolute and relative errors.

Show solution
  1. \(E_a = |9.81 - 9.78| = 0.03\) m/s².
  2. \(E_r = 0.03/9.81 = 0.0031\), or 0.31%.

Answer: Absolute error 0.03 m/s², relative error 0.31%: about two to three significant figures are correct

Where errors come from

A numerical result passes through several stages, and each adds error:

  • Modeling error: the equations simplify reality (a beam treated as perfectly elastic, air resistance ignored, a soil layer assumed uniform).
  • Data error: inputs are measured or estimated (loads, material properties, flow rates), each with its own uncertainty.
  • Truncation error: the numerical method approximates an exact mathematical operation, such as a derivative by a finite difference, an integral by a sum, or an infinite series by a few terms.
  • Round-off error: the computer stores and computes with a finite number of digits.
A chain of five boxes from left to right: physical system, mathematical model, numerical method, computer and result. Under the arrows the error introduced at each step is named: modeling and data error, truncation error and round-off error. A note says blunders can enter anywhere and are caught by checks and independent review.
Each step from reality to a computed number introduces its own kind of error.

The numerical analyst controls the last two. Neither is useful to reduce far below the first two: computing a stress to 12 significant figures is pointless if the load is known to 10%. But truncation and round-off can also grow far beyond the data error if a method is badly chosen, and that is what this course teaches you to prevent.

How computers store numbers

Computers store real numbers in binary floating point, a kind of scientific notation in base 2:

\[x = \pm (1.b_1b_2b_3\ldots b_{52})_2 \times 2^{e}\]

The IEEE 754 double-precision format, used by Python, MATLAB, Excel and almost all engineering software, has 64 bits: 1 for the sign, 11 for the exponent e (about −1022 to 1023) and 52 for the fraction. This gives about 16 significant decimal digits and a range from about \(10^{-308}\) to \(10^{308}\). Single precision (32 bits, 24 significant bits) gives only about 7 digits and is used where memory or speed matters more, as in graphics cards and many sensors.

The key number is machine epsilon, the gap between 1 and the next larger representable number:

\[\varepsilon_{\text{mach}} = 2^{-52} \approx 2.22 \times 10^{-16} \quad \text{(double)}, \qquad 2^{-23} \approx 1.19 \times 10^{-7} \quad \text{(single)}\]

Every arithmetic operation is rounded to the nearest representable number, so each one can introduce a relative error of up to about \(\varepsilon_{\text{mach}}/2\). Representable numbers are not evenly spaced: the gaps grow in proportion to the size of the number, which is what keeps the relative error roughly constant.

A number line from 0 to 8 for a toy floating-point system with 3 fraction bits. Tick marks are densely packed near 0, spaced 1/8 apart between 1 and 2, 1/4 apart between 2 and 4, and 1/2 apart between 4 and 8; the spacing doubles at each power of 2.
A toy floating-point system with 3 fraction bits. The spacing doubles at every power of two, so the relative spacing stays the same.

Many simple decimal fractions have no exact binary representation, just as 1/3 has none in decimal. The number 0.1 in binary is 0.000110011001100… repeating forever, so it is stored rounded. This is why, in Python, 0.1 + 0.2 gives 0.30000000000000004 and the test 0.1 + 0.2 == 0.3 is False.

Worked problem

The Patriot missile clock

During the 1991 Gulf War, a Patriot air-defense battery at Dhahran, Saudi Arabia, kept time by counting tenths of a second and multiplying by 0.1 stored in a 24-bit register. The chopped binary value of 0.1 was 0.0999999046…, too small by about \(9.5 \times 10^{-8}\). The battery had run for about 100 hours. How large was the timing error, and how far does a Scud missile traveling at about 1676 m/s move in that time?

Show solution
  1. 100 hours is \(100 \times 3600 \times 10 = 3.6 \times 10^6\) tenths of a second.
  2. Accumulated error: \(3.6 \times 10^6 \times 9.5 \times 10^{-8} = 0.34\) s.
  3. Distance: \(1676 \times 0.34 \approx 575\) m.

Answer: About 0.34 s, during which a Scud travels more than half a kilometer. On February 25, 1991 the battery's range gate looked in the wrong place, failed to intercept an incoming Scud, and 28 soldiers were killed. A tiny representation error, multiplied by millions of steps, became a fatal one

Round-off error accumulates

One rounding error of \(10^{-16}\) is harmless. Trouble comes when millions of them accumulate, or when a calculation magnifies one.

Worked problem

Adding 0.1 a million times

What does a computer get when it adds 0.1 to a running total one million times, in double precision and in single precision?

Show solution
  1. The exact answer is 100 000.
  2. Double precision: 100 000.00000133, an error of about \(1.3 \times 10^{-6}\).
  3. Single precision: 100 958.34, an error of almost 1%.

Answer: Double precision is accurate to about 12 digits here; single precision loses most of its accuracy, because once the total is large each added 0.1 is rounded coarsely. Accurate summation algorithms (math.fsum in Python, Kahan summation) recover the exact 100 000

A famous financial example: in 1982 the Vancouver Stock Exchange started a new index at 1000.000 and recomputed it thousands of times a day, truncating (chopping) each result to three decimals instead of rounding. Each chop lost a little, always in the same direction. By late 1983 the index stood at about 524.8, when the correctly computed value was about 1098.9.

Catastrophic cancellation

Subtracting two nearly equal numbers destroys significant figures. If a = 1.23456789 and b = 1.23456700, each known to 9 digits, then a − b = 0.00000089 has only 2 significant digits left. The subtraction itself is exact; it exposes the rounding errors that were already in a and b.

Worked problem

A quadratic that defeats the formula

Find the small root of \(x^2 + 10^8 x + 1 = 0\) in double precision.

Show solution
  1. The usual formula gives \(x_1 = \dfrac{-b + \sqrt{b^2 - 4ac}}{2a}\). With \(b = 10^8\), \(\sqrt{b^2 - 4} \approx b\), and the numerator subtracts two nearly equal numbers. The computer returns \(-7.45 \times 10^{-9}\).
  2. The true small root is very close to \(-10^{-8}\): the computed value is 25% wrong.
  3. Rearrange to avoid the subtraction. Since \(x_1x_2 = c/a\), compute the large root safely, \(x_2 = (-b - \sqrt{b^2 - 4ac})/2a = -10^8\), then \(x_1 = c/(a x_2)\). Equivalently \(x_1 = \dfrac{2c}{-b - \sqrt{b^2 - 4ac}}\).

Answer: The stable formula gives \(x_1 = -1.000 \times 10^{-8}\), correct to full precision. Same mathematics, different arithmetic, completely different accuracy

Other common fixes: compute \(1 - \cos x\) for small x as \(2\sin^2(x/2)\) (at \(x = 10^{-8}\) the direct form gives exactly 0, the rewritten one \(5 \times 10^{-17}\)), and use library functions such as log1p(x) and expm1(x), which are designed for arguments near zero.

Truncation error and Taylor series

Truncation error comes from approximating an infinite process by a finite one. Taylor series (MATH-101) are the main tool for analyzing it:

\[f(x + h) = f(x) + hf'(x) + \frac{h^2}{2}f''(x) + \frac{h^3}{6}f'''(x) + \cdots\]

Cutting the series after a few terms leaves an error about the size of the first omitted term. For example, \(e^{0.5}\) from the series \(1 + x + x^2/2! + \cdots\) has errors of 0.149, 0.024, 0.0029 and 0.00028 after 2, 3, 4 and 5 terms: each extra term buys about one more digit.

Finite differences and the best step size

Rearranging the Taylor series gives the forward difference approximation of a derivative and its truncation error:

\[f'(x) \approx \frac{f(x + h) - f(x)}{h}, \qquad \text{error} \approx \frac{h}{2}|f''(x)| = O(h)\]

Subtracting the series for \(f(x - h)\) from that for \(f(x + h)\) cancels the \(h^2\) terms and gives the more accurate central difference:

\[f'(x) \approx \frac{f(x + h) - f(x - h)}{2h}, \qquad \text{error} \approx \frac{h^2}{6}|f'''(x)| = O(h^2)\]

The notation O(h) means the error shrinks in proportion to h; O(h²) means it shrinks with h²: halving h divides the error by 4. That is the order of the method.

But h cannot be made arbitrarily small. The numerator subtracts two nearly equal values, so its round-off error is about \(\varepsilon_{\text{mach}}|f|\), and dividing by a tiny h magnifies it. Total error is truncation (falling with h) plus round-off (rising as h shrinks), and there is a best h in between.

Log-log plot of the error in the derivative of sin x at x = 1 against step size h from 1e-13 to 0.1. The forward difference error falls with slope 1 as h decreases until about h = 1e-8, then rises. The central difference error falls with slope 2 until about h = 1e-5, reaching about 1e-11, then rises. To the left of the minimum both curves are dominated by round-off.
Error in the derivative of sin x at x = 1. Truncation error dominates for large h, round-off for small h.

Worked problem

Differentiating sin x numerically

Estimate the derivative of sin x at x = 1 (exact value cos 1 = 0.540302…) with forward and central differences for h = 0.01, 10⁻⁶ and 10⁻¹².

Show solution
  1. h = 0.01: forward error \(4.2 \times 10^{-3}\); central error \(9.0 \times 10^{-6}\).
  2. h = 10⁻⁶: forward error \(4.2 \times 10^{-7}\); central error \(2.8 \times 10^{-11}\).
  3. h = 10⁻¹²: forward error \(4.3 \times 10^{-5}\); central error \(1.2 \times 10^{-5}\). Both are worse than at h = 10⁻⁶: round-off has taken over.

Answer: The central difference is far more accurate for reasonable h. The best h is about \(\sqrt{\varepsilon_{\text{mach}}} \approx 10^{-8}\) for the forward difference and about \(\varepsilon_{\text{mach}}^{1/3} \approx 10^{-5}\) for the central one. Smaller is not better

Conditioning and stability

Two ideas separate the problem from the method. A problem is ill-conditioned if small changes in the input cause large changes in the exact answer. For a function, the condition number compares relative changes:

\[\kappa = \left|\frac{x f'(x)}{f(x)}\right|\]

With κ = 1000, a relative input error of \(10^{-6}\) can become \(10^{-3}\) in the output, whatever method is used. Examples are tan x near π/2, the roots of polynomials with clustered roots, and the linear systems of Lesson 3 whose matrices are nearly singular.

A method (algorithm) is stable if it does not magnify the round-off errors it creates, and unstable if it does. The naive quadratic formula above is an unstable algorithm for a well-conditioned problem: the roots themselves are not sensitive to the coefficients, but the subtraction in the formula is. Good numerical practice means using stable algorithms and recognising ill-conditioned problems, where the remedy is better data or a reformulated problem rather than more digits.

Floating-point surprises, cancellation and step size in Python
import math
import numpy as np

print(0.1 + 0.2, 0.1 + 0.2 == 0.3, math.isclose(0.1 + 0.2, 0.3))
print("double eps:", np.finfo(float).eps, " single eps:", np.finfo(np.float32).eps)

# small root of x^2 + 1e8 x + 1 = 0
a, b, c = 1.0, 1e8, 1.0
d = math.sqrt(b*b - 4*a*c)
print("naive :", (-b + d) / (2*a))
print("stable:", (2*c) / (-b - d))

# best step for a central difference
for h in [1e-2, 1e-5, 1e-8, 1e-11]:
    est = (math.sin(1 + h) - math.sin(1 - h)) / (2*h)
    print(f"h = {h:.0e}  error = {abs(est - math.cos(1)):.1e}")

Output: 0.30000000000000004 False True; double eps: 2.220446049250313e-16, single eps: 1.1920929e-07; naive: -7.450580596923828e-09, stable: -1e-08; central difference errors 9.0e-06, 1.1e-11, 2.6e-09 and 1.2e-06 for h = 10⁻², 10⁻⁵, 10⁻⁸ and 10⁻¹¹: best near h = 10⁻⁵, then growing again.

Common mistakes

  • MistakeTesting floating-point numbers for exact equality.

    InsteadCompare with a tolerance, such as math.isclose(a, b).

  • MistakeAssuming a smaller step size always gives a more accurate derivative.

    InsteadBelow an optimal h, round-off error grows; for central differences use h around 10⁻⁵ times the scale of x.

  • MistakeSubtracting nearly equal quantities without thinking.

    InsteadRearrange formulas (stable quadratic formula, 2sin²(x/2), log1p, expm1) to avoid cancellation.

  • MistakeReporting results to 15 digits because the computer printed them.

    InsteadReport the accuracy justified by the data and the method.

  • MistakeBlaming the computer for an ill-conditioned problem.

    InsteadIf κ is large, no method can do better than the data allow; improve the data or reformulate.

  • MistakeUsing single precision for long accumulations to save memory.

    InsteadAccumulate in double precision, or use compensated summation.

Summary and key terms

  • Absolute error |p − p̃|; relative error |p − p̃|/|p|. Iterations stop when the approximate relative error is below a tolerance.
  • Errors come from the model, the data, truncation of mathematical processes, and round-off.
  • IEEE double precision stores about 16 significant digits; machine epsilon is 2.22 × 10⁻¹⁶. Many decimals, such as 0.1, are not exact in binary.
  • Round-off accumulates over many operations and is magnified by subtracting nearly equal numbers (catastrophic cancellation).
  • Truncation error is analyzed with Taylor series; forward differences are O(h), central differences O(h²). Total error has an optimal step size.
  • Conditioning is a property of the problem (κ = |xf′/f|); stability is a property of the algorithm.
Absolute error
The magnitude of the difference between the true and approximate values.
Relative error
Absolute error divided by the magnitude of the true value.
Truncation error
Error from approximating an exact mathematical process by a finite one.
Round-off error
Error from storing and computing numbers with finite precision.
Floating point
Binary scientific notation with a fixed number of significant bits.
Machine epsilon
The gap between 1 and the next representable number; 2.22 × 10⁻¹⁶ in double precision.
Catastrophic cancellation
Loss of significant digits when subtracting nearly equal numbers.
Finite difference
An approximation of a derivative from function values at nearby points.
Order of a method
The power of h to which the truncation error is proportional.
Condition number
A measure of how sensitive a problem's answer is to changes in its input.
Ill-conditioned
Having a large condition number, so small input changes cause large output changes.
Stable algorithm
An algorithm that does not magnify round-off errors.

Practice problems

Work each problem on paper first, then reveal the answer to check.

  1. A 250.0 mm part is measured as 249.6 mm. Find the absolute and relative errors.

    Show answer

    0.4 mm; 0.4/250 = 0.0016 = 0.16%.

  2. Successive iterates are 2.31476 and 2.31458. Find the approximate relative error. Is it below 10⁻⁴?

    Show answer

    |2.31458 − 2.31476|/2.31458 = 7.8 × 10⁻⁵: yes.

  3. About how many significant decimal digits does single precision carry? Why?

    Show answer

    About 7: 24 significant bits give relative precision 2⁻²³ ≈ 1.2 × 10⁻⁷.

  4. Why does 0.5 + 0.25 == 0.75 evaluate to True in Python while 0.1 + 0.2 == 0.3 is False?

    Show answer

    0.5, 0.25 and 0.75 are exact binary fractions; 0.1, 0.2 and 0.3 are not.

  5. Rewrite √(x + 1) − √x to avoid cancellation for large x.

    Show answer

    Multiply by the conjugate: 1/(√(x + 1) + √x).

  6. Using the forward difference with h = 0.1, estimate the derivative of x² at x = 3. What is the error, and how does it compare with (h/2)f″?

    Show answer

    (3.1² − 9)/0.1 = 6.1; error 0.1 = (0.1/2)(2) exactly.

  7. Repeat with the central difference.

    Show answer

    (3.1² − 2.9²)/0.2 = 6.0: exact, since f‴ = 0 for a quadratic.

  8. If halving h reduces an error from 8 × 10⁻⁴ to 2 × 10⁻⁴, what is the order of the method?

    Show answer

    The error falls by 4 = 2², so second order.

  9. Find the condition number of f(x) = √x. Is square root well conditioned?

    Show answer

    κ = |x (1/(2√x))/√x| = 1/2: very well conditioned.

  10. Find the condition number of f(x) = x − 1 at x = 1.001 and explain.

    Show answer

    κ = |1.001 × 1/0.001| ≈ 1000: subtracting nearly equal numbers is ill-conditioned.

Lesson quiz · 5 questions

Score 60% or more to complete this lesson.

Take the quiz