Quadratic equation solver

Solve ax² + bx + c = 0. The formula everybody learns returns zero for one of the roots of x² − 10&sup9;x + 1, and the other root is perfect — so nothing looks wrong. Nothing you type here leaves your browser — it is worked out on your own device, so there is nothing to send and nothing to log.

ax² + bx + c = 0

The formula you were taught loses one of the roots

Not “is slightly inaccurate”. Loses it. Solve x² − 1,000,000,000x + 1 = 0 with (−b ± √(b²−4ac)) ÷ 2a and the small root comes out as exactly zero. The answer is 0.000000001.

And the other root is perfect. So nothing about the output looks wrong: you get two numbers, one of them correct to sixteen digits and the other a hundred per cent wrong, with no warning of any kind. That is the default behaviour of the quadratic solver in a great many spreadsheets, textbooks and programming courses.

Why: catastrophic cancellation

When b² is much bigger than 4ac, the square root of the discriminant is very nearly |b|. So one of the two branches computes −b plus something almost exactly equal to b, and subtracting two nearly equal numbers throws away every digit they had in common.

With b = 10&sup9;, √(b²−4ac) agrees with b for about sixteen digits — which is every digit a double has — so the subtraction leaves nothing at all. The name for this is catastrophic cancellation, and it is the oldest documented trap in numerical computing.

The fix is a hundred years old

Compute only the branch that adds, so no cancellation can occur:

q = −(b + sign(b) × √(b² − 4ac)) ÷ 2

Then get the second root from the fact that the two roots multiply to c/a:

x₁ = q ÷ a     x₂ = c ÷ q

No subtraction of near-equal quantities anywhere. Measured against sixty digits of exact decimal arithmetic, this form is accurate to the last bit on every case this site tests, and the textbook form reaches 100% error. It also agrees with numpy's eigenvalue solver, which finds the roots as the eigenvalues of the companion matrix and never evaluates the quadratic formula at all.

The sign(b) is not decoration. Drop it and the arrangement is correct for positive b and wrong for negative b — right exactly half the time, which is the hardest kind of wrong to notice.

What the discriminant tells you

b² − 4ac > 0Two different real roots.
b² − 4ac = 0One root, repeated. Not two roots that happen to be equal — one value, with multiplicity two. The parabola touches the axis rather than crossing it.
b² − 4ac < 0No real roots. Two complex ones, conjugates of each other, shown here as p ± qi.

And if a is zero it is not a quadratic

It is a straight line, with one root at −c/b — and dividing by 2a would be dividing by zero. If both a and b are zero it is either an identity (c = 0, every number works) or a contradiction (c ≠ 0, no number does). All three are answered rather than crashed on.

What it will not do

Where to go next