Skip to content
ihateDesmos

Why sin(π) isn’t zero on your computer

· 9 min read · ihateDesmos

Ask almost any programming language for sin(π) and it answers 0.00000000000000012246. Ask for 0.1 + 0.2 and you get 0.30000000000000004. Neither is a bug. Both come from the way computers store numbers, and a calculator has to work to hide them.

Numbers in binary

Computers store most numbers in IEEE 754 double precision: a sign, an exponent, and 53 significant binary digits. That is about 15 to 17 significant decimal digits, which is plenty for almost anything. But it means only numbers that are exact binary fractions can be stored exactly.

0.5 is ½, an exact binary fraction. 0.1 is not: in binary it is 0.000110011001100…, repeating forever, just as ⅓ = 0.333… repeats in decimal. The computer stores the nearest double, which is very slightly more than 0.1. The same happens for 0.2. Adding the two stored values gives a number whose nearest double is not the nearest double to 0.3, so the sum prints as 0.30000000000000004.

Why sin(π) isn’t 0

π has infinitely many digits, so the stored value of π is not π. It is π rounded to 53 binary digits, which is about 1.2246 × 10⁻¹⁶ less than the true π. The sine function is computed very accurately, to within a fraction of a unit in the last place, and it faithfully returns the sine of the number it was given. Near π the sine curve has slope −1, so sin(π − ε) ≈ ε. The answer, 1.2246467991473532e-16, is the size of the rounding error in π itself.

The same thing makes tan(π/2) come out as 16331239353195370 instead of undefined: the stored π/2 is a hair below the true value, where tangent is enormous but finite.

A gallery of small lies

ExpressionRaw double-precision resultThis calculator
0.1 + 0.20.300000000000000040.3
sin(π)1.2246467991473532e-160
cos(π/2)6.123233995736766e-170
tan(π/2)16331239353195370undefined
(−8)^(1/3)NaN−2
(1 − cos(10⁻⁸)) / 10⁻¹⁶00

The last row is the most instructive, and the calculator does not fix it. The true value is very close to ½, because 1 − cos x ≈ x²/2 for small x. But cos(10⁻⁸) is so close to 1 that the double nearest to it is exactly 1, and the subtraction gives 0. This is catastrophic cancellation: subtracting two nearly equal numbers wipes out the significant digits that distinguished them. No amount of display formatting can recover information that was rounded away before the subtraction. The cure is algebra: rewrite 1 − cos x as 2 sin²(x/2), which has no cancellation, or evaluate with more digits.

What a careful calculator does

Hiding floating-point noise without hiding real information takes several separate techniques. These are the ones this calculator uses.

  • Exact special values. Trigonometric functions recognise arguments that are exact multiples of π/2, so sin(π) is 0, cos(π/2) is 0, and tan(π/2) is undefined rather than a huge number. This is checked on the argument before the function is called, not by rounding the result, so sin(10⁻²⁰) is still 10⁻²⁰.
  • Showing 12 significant digits. Doubles carry about 16. Showing 12 means the last few, where rounding errors live, are not displayed, so 0.1 + 0.2 shows as 0.3. Copying a value gives the full 15 digits if you need them.
  • Real roots of negative numbers. Math.pow(−8, 1/3) is NaN because 1/3 can’t be stored exactly and a negative number raised to a non-integer power has no real value. A calculator should recognise that the user meant the cube root, which is −2.
  • Compensated summation. Adding many numbers of different sizes loses precision with each addition. The sum() function uses Kahan summation, which carries the rounding error of each step into the next.
  • Error estimates. Integrals are computed with adaptive Gauss–Kronrod quadrature and reported with an estimate of their error, so you know how many digits to believe.
  • More digits on request. For a constant, the 50 digits button re-evaluates the expression with 50-digit decimal arithmetic. Typing (1 - cos(10^-8))/10^-16 and asking for 50 digits gives 0.49999999999999999583333333333333334722222222222222, the right answer.

Rounding is not the same as wrong

Floating point is not broken. Double precision is accurate to about one part in 10¹⁶, a precision no physical measurement comes close to. The errors only become visible in two situations: when an exact answer is expected (0, ½, π) and a tiny error shows up in the display, and when a calculation amplifies small errors, as cancellation and ill-conditioned problems do. A good calculator handles the first with care at the edges and makes the second visible instead of hiding it.

The practical lesson for anyone computing: if a result should be exact, check it with algebra; if a formula subtracts nearly equal quantities, look for a rearrangement; and when it matters, ask for an error estimate rather than trusting the last digits.

Read next

See it for yourself

Every figure in this post opens in the calculator, where you can change it and watch what happens.

Open the calculator