Python programs / Numbers / Quadratic equation roots

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

  1. math.sqrt() works out square roots of numbers from 0 up. The cmath module (complex math) has a sqrt() that takes negative numbers too.
  2. 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.
  3. 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.
  4. When it's positive, it has an ordinary square root, so there are two real roots.
  5. 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) is 4j (Python writes the imaginary unit i as j).
  6. The formula, once with + and once with −, gives the two roots. With an imaginary square root, they're complex numbers.
  7. 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 + c should give 0, or very nearly, as floats are rounded.
  • Try a = 0: the program fails with a ZeroDivisionError, because without the x² term the equation isn't quadratic. Make it return a message instead.

More numbers programs

Share this program