C Program to Find All Roots of a Quadratic Equation

C Program to Find All Roots of a Quadratic Equation

A science exercise asks for roots of ax² + bx + c. Check whether the equation is actually quadratic before dividing by 2a.

For a nonzero quadratic coefficient, the discriminant b²−4ac determines whether the roots are two real roots, a repeated real root or a complex-conjugate pair.

Before this exercise, review arithmetic and conversions and numeric types and their limits. The worked program below applies those ideas to this specific problem.

  1. Explain

    Explain why quadratic roots uses this sequence of operations.

  2. Trace

    Trace the sample values and predict the printed result.

  3. Apply

    Use a=1, b=0 and c=1 and identify why the result is complex.

Quadratic Roots: follow the data

  1. Given data

    A science exercise asks for roots of ax² + bx + c. Check whether the equation is actually quadratic before dividing by 2a.

  2. Rule

    For a nonzero quadratic coefficient, the discriminant b²−4ac determines whether the roots are two real roots, a repeated real root or a complex-conjugate pair.

  3. Observed result

    Roots: -1.00 -2.00

A guided model of this example. The illustration explains the process; run the complete C program to check its output.

Understand the operation

The direct formula uses (-b ± sqrt(discriminant))/(2a). A negative discriminant uses the square root of its magnitude for the imaginary part instead of asking sqrt to evaluate a negative real value.

When a is zero, use the linear equation if b is nonzero; otherwise c determines whether every value or no value is a solution. The complete C example includes those branches even though its first fixture is quadratic.

Read the complete C program

The input values are written into this complete C17 example so the calculation can be reproduced without an unavailable service. Change the named data, rebuild and compare the actual output with your prediction.

C17 · complete program

#include <stdio.h>
#include <math.h>
int main(void) {
  double a = 1.0, b = 3.0, c = 2.0;
  if (a == 0.0) {
    if (b != 0.0) printf("Linear root: %.2f\n", -c / b);
    else puts(c == 0.0 ? "Every value is a solution" : "No solution");
  } else {
    double discriminant = b * b - 4.0 * a * c;
    if (discriminant >= 0.0) {
      double root = sqrt(discriminant);
      printf("Roots: %.2f %.2f\n", (-b + root) / (2.0 * a), (-b - root) / (2.0 * a));
    } else {
      double real = -b / (2.0 * a), imaginary = sqrt(-discriminant) / fabs(2.0 * a);
      printf("Roots: %.2f + %.2fi and %.2f - %.2fi\n", real, imaginary, real, imaginary);
    }
  }
  return 0;
}

Expected output

Roots: -1.00 -2.00
Run in C compiler →

Follow the values through the code

C17 · code used in this explanation

#include <stdio.h>
#include <math.h>
int main(void) {
  double a = 1.0, b = 3.0, c = 2.0;
  if (a == 0.0) {
    if (b != 0.0) printf("Linear root: %.2f\n", -c / b);
    else puts(c == 0.0 ? "Every value is a solution" : "No solution");
  } else {
    double discriminant = b * b - 4.0 * a * c;
    if (discriminant >= 0.0) {
      double root = sqrt(discriminant);
      printf("Roots: %.2f %.2f\n", (-b + root) / (2.0 * a), (-b - root) / (2.0 * a));
    } else {
      double real = -b / (2.0 * a), imaginary = sqrt(-discriminant) / fabs(2.0 * a);
      printf("Roots: %.2f + %.2fi and %.2f - %.2fi\n", real, imaginary, real, imaginary);
    }
  }
  return 0;
}

For a=1, b=3 and c=2, the discriminant is 9−8=1.

Its square root is one. The two numerators are -2 and -4, divided by two to give -1 and -2.

Follow the worked calculation

  1. Start with the sample

    For a=1, b=3 and c=2, the discriminant is 9−8=1.

  2. Apply the rule

    Its square root is one. The two numerators are -2 and -4, divided by two to give -1 and -2.

  3. Check the result

    Roots: -1.00 -2.00

    Roots: -1.00 -2.00
A guided model of this example. The illustration explains the process; run the complete C program to check its output.

Try a small variation

C17 · code used in this explanation

#include <stdio.h>
#include <math.h>
int main(void) {
  double a = 1.0, b = 3.0, c = 2.0;
  if (a == 0.0) {
    if (b != 0.0) printf("Linear root: %.2f\n", -c / b);
    else puts(c == 0.0 ? "Every value is a solution" : "No solution");
  } else {
    double discriminant = b * b - 4.0 * a * c;
    if (discriminant >= 0.0) {
      double root = sqrt(discriminant);
      printf("Roots: %.2f %.2f\n", (-b + root) / (2.0 * a), (-b - root) / (2.0 * a));
    } else {
      double real = -b / (2.0 * a), imaginary = sqrt(-discriminant) / fabs(2.0 * a);
      printf("Roots: %.2f + %.2fi and %.2f - %.2fi\n", real, imaginary, real, imaginary);
    }
  }
  return 0;
}

Use a=1, b=0 and c=1 and identify why the result is complex.

Worked answer

The discriminant is -4. The real part is zero and the imaginary magnitude is one. The sample may display signed negative zero from floating-point arithmetic; it represents the same zero real part here.

C17 · complete program

#include <stdio.h>
#include <math.h>
int main(void) {
  double a = 1.0, b = 0.0, c = 1.0;
  if (a == 0.0) {
    if (b != 0.0) printf("Linear root: %.2f\n", -c / b);
    else puts(c == 0.0 ? "Every value is a solution" : "No solution");
  } else {
    double discriminant = b * b - 4.0 * a * c;
    if (discriminant >= 0.0) {
      double root = sqrt(discriminant);
      printf("Roots: %.2f %.2f\n", (-b + root) / (2.0 * a), (-b - root) / (2.0 * a));
    } else {
      double real = -b / (2.0 * a), imaginary = sqrt(-discriminant) / fabs(2.0 * a);
      printf("Roots: %.2f + %.2fi and %.2f - %.2fi\n", real, imaginary, real, imaginary);
    }
  }
  return 0;
}

Expected output

Roots: -0.00 + 1.00i and -0.00 - 1.00i
Run in C compiler →

Recognize the important boundaries

The direct formula can lose precision when nearly equal values are subtracted. This small-coefficient teaching example is not a numerically robust general solver.

On toolchains requiring a separate math library, link with -lm. Exact zero tests here describe exact literal fixtures, not a universal tolerance policy for measured coefficients.

Check your understanding

Choose the answer, then compare the reasoning for every option.

What must be checked before dividing by 2a?
Choose one answer. You can try again.

Answer and explanation

Whether a is zero.

Correct. A zero leading coefficient makes the quadratic formula inapplicable.

Check your understanding

Choose the answer, then compare the reasoning for every option.

What does a negative discriminant mean in this real-coefficient example?
Choose one answer. You can try again.

Answer and explanation

A complex-conjugate pair.

Correct. The imaginary parts have equal magnitudes and opposite signs.

Use the idea independently

For a nonzero quadratic coefficient, the discriminant b²−4ac determines whether the roots are two real roots, a repeated real root or a complex-conjugate pair.

Continue with floating-point calculations.

Language reference: WG14 C11 committee draft. These examples use the C17-compatible subset of the explained language features.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: C Quadratic Roots: Cases →