Python Program to Find the Roots of a Quadratic Equation
Beginner Numbers
Finds the roots of ax² + bx + c = 0 from the discriminant: two real roots, one repeated root, or two complex roots.
A quadratic equation has the form ax² + bx + c = 0, where a isn't 0. Its roots are the values of x that make it true, and the quadratic formula gives them: x = (−b ± √(b² − 4ac)) / 2a. For x² − 5x + 6 = 0, a is 1, b is −5 and c is 6, so b² − 4ac = 25 − 24 = 1 and x = (5 ± 1) / 2: the roots are 3 and 2.
Program
import cmath
import math
def quadratic_roots(a, b, c):
"""The roots of a*x**2 + b*x + c = 0, in a list."""
discriminant = b ** 2 - 4 * a * c
if discriminant == 0:
return [-b / (2 * a)] # one repeated root
if discriminant > 0:
root = math.sqrt(discriminant) # two real roots
else:
root = cmath.sqrt(discriminant) # two complex roots
return [(-b + root) / (2 * a), (-b - root) / (2 * a)]
print("x^2 - 5x + 6 = 0:", quadratic_roots(1, -5, 6))
print("x^2 + 2x + 1 = 0:", quadratic_roots(1, 2, 1))
print("x^2 + 2x + 5 = 0:", quadratic_roots(1, 2, 5))
Open in the editor Download quadratic_roots.py
Output
x^2 - 5x + 6 = 0: [3.0, 2.0]
x^2 + 2x + 1 = 0: [-1.0]
x^2 + 2x + 5 = 0: [(-1+2j), (-1-2j)]
How it works
Step through the program line by line: each step below shows up as its line runs.
-
math.sqrt()works out square roots of numbers from 0 up. Thecmathmodule (complex math) has asqrt()that takes negative numbers too. - The discriminant, b² − 4ac, is the part of the formula under the square root. Its sign decides how many roots there are, and what kind.
- When it's 0, the ± adds and subtracts nothing, so both roots are the same number, −b / 2a: a repeated root. The list holds it once.
- When it's positive, it has an ordinary square root, so there are two real roots.
- When it's negative, no real number squared gives it, and
math.sqrt()would raise an error.cmath.sqrt()returns an imaginary number instead:cmath.sqrt(-16)is4j(Python writes the imaginary unit i asj). - The formula, once with + and once with −, gives the two roots. With an imaginary square root, they're complex numbers.
- The program solves one equation of each kind. For x² + 2x + 5 = 0 the discriminant is 4 − 20 = −16, so the roots are (−2 ± 4j) / 2: −1 + 2j and −1 − 2j.
Other ways to write it
With cmath for every case
cmath.sqrt() works whatever the sign, so one formula covers all three cases. The catch: every root comes back as a
complex number, even a real one, as (3+0j).
import cmath
def quadratic_roots(a, b, c):
root = cmath.sqrt(b ** 2 - 4 * a * c)
return (-b + root) / (2 * a), (-b - root) / (2 * a)
print(quadratic_roots(1, -5, 6))Complex roots without cmath
Many textbooks write complex roots in two parts: a real part, −b / 2a, and an imaginary part, √(4ac − b²) / 2a, with
i. math.sqrt() is enough for that, since 4ac − b² is positive when the discriminant is negative.
import math
def complex_roots(a, b, c):
real = -b / (2 * a)
imaginary = math.sqrt(4 * a * c - b ** 2) / (2 * a)
return f"{real} + {imaginary}i and {real} - {imaginary}i"
print(complex_roots(1, 2, 5))Try it yourself
- Solve 2x² − 4x − 6 = 0, as
quadratic_roots(2, -4, -6): the roots are 3.0 and -1.0. - Solve x² − 2 = 0, where b is 0: the roots are √2 and −√2, about 1.414 and -1.414.
- Check a root by putting it back into the equation:
a * x ** 2 + b * x + cshould give 0, or very nearly, as floats are rounded. - Try
a = 0: the program fails with aZeroDivisionError, because without the x² term the equation isn't quadratic. Make it return a message instead.