Solving Cubic Polynomials

Tavian Barnes

Although a closed form solution exists for the roots of polynomials of degree ≤ 4, the general formulae for cubics (and quartics) is ugly. Various simplifications can be made; commonly, the cubic a3x3+a2x2+a1x+a0a_3 x^3 + a_2 x^2 + a_1 x + a_0 is transformed by substituting x=ta2/3a3x = t - a_2 / 3 a_3, giving

t3+pt+q=0,t^3 + p t + q = 0,


p=1a3(a1a223a3)q=1a3(a0a2a13a32a2327a32).\begin{aligned} p &= \frac{1}{a_3} \left( a_1 - \frac{a_2^2}{3 a_3} \right) \\ q &= \frac{1}{a_3} \left( a_0 - \frac{a_2 a_1}{3 a_3} - \frac{2 a_2^3}{27 a_3^2} \right). \end{aligned}

Several strategies exist for solving this depressed cubic, but most involve dealing with complex numbers, even when we only want to find real roots. Fortunately, there are a couple ways to find solutions with only real arithmetic. First, we need to know the value of the discriminant Δ=4p3+27q2\Delta = 4 p^3 + 27 q^2.

If Δ<0\Delta < 0, then there are three real roots; this is the tough case. Luckily, we can use the uncommon trigonometric identity 4cos3(θ)3cos(θ)cos(3θ)=04 \cos^3(\theta) - 3 \cos(\theta) - \cos(3 \theta) = 0 to calculate the roots with trig functions. Making another substitution, t=2p/3cos(θ)t = 2 \sqrt{-p/3} \cos(\theta), gives us

4cos3(θ)3cos(θ)3q2p3p=0,4 \cos^3(\theta) - 3 \cos(\theta) - \frac{3 q}{2 p} \sqrt{\frac{-3}{p}} = 0,


cos(3θ)=3q2p3p.\cos(3 \theta) = \frac{3 q}{2 p} \sqrt{\frac{-3}{p}}.

Thus the three roots are:

tn=2p3cos(13cos1(3q2p3p)2πn3),t_n = 2 \sqrt{\frac{-p}{3}} \cos \left( \frac{1}{3} \cos^{-1} \left( \frac{3 q}{2 p} \sqrt{\frac{-3}{p}} \right) - \frac{2 \pi n}{3} \right),

for n{0,1,2}n \in \{0, 1, 2\}. We can save a cosine calculation by noting that t2=t0q=qt_2 = -t_0 |_{q = -q} and t1=(t0+t2)t_1 = -(t_0 + t_2). When generated in this way, the roots are ordered from smallest to largest (t0<t1<t2t_0 < t_1 < t_2).

For the Δ>0\Delta > 0 case, there is a single real root. We can apply the general cubic formula and avoid dealing with complex numbers, provided we choose the signs right. In this case,

t=sgn(q)(Cp3C), where C=Δ108+q23.t = -\mathrm{sgn}(q) \left( C - \frac{p}{3 C} \right), \text{ where } C = \sqrt[3]{\sqrt{\frac{\Delta}{108}} + \frac{|q|}{2}}.

When Δ=0\Delta = 0, there is a root of at least multiplicity 2, and we can avoid calculating any radicals. If p=0p = 0, the only root is t0=0t_0 = 0; otherwise, the duplicate root is 3q/2p-3 q /2 p and the simple root is 3q/p3 q / p.

My C implementation of this solution method can be seen in the dmnsn_solve_cubic() function here.