Determine the roots of a Quadratic Equation

A code that determines the roots of a quadratic equation. Also, determine the following based on the discriminant b² – 4ac:

If b² − 4ac is positive, display: “There are TWO REAL SOLUTIONS.”

If b² − 4ac is zero, display: “There is ONLY ONE REAL SOLUTION.”

If b² − 4ac is negative, display: “There are TWO COMPLEX SOLUTIONS.”

#include <stdio.h>
#include <math.h>

int main(){

int a, b, c, d;
double root1_real, root2_real, root1_complex, root1_i, root2_complex, root2_i, root_zero;

printf("Enter a, b and c where a*x*x + b*x + c = 0\n");
scanf("%d %d %d", &a, &b, &c);

d = b * b - 4 * a * c;

if(d > 0){ // Positive
root1_real = (-b + sqrt(d)) / (2*a);
root2_real = (-b - sqrt(d)) / (2*a);
printf("First Root : %.2lf\n", root1_real);
printf("Second Root : %.2lf\n", root2_real);
printf("There are TWO REAL SOLUTIONS\n");
}else if(d < 0){ // Negative
root1_complex = -b / (2 * a); root1_i = sqrt(-d) / (2 * a);
root2_complex = -b / (2 * a); root2_i = sqrt(-d) / (2 * a);
printf("First root : %.2lf + i%.2lf\n", root1_complex, root1_i);
printf("Second root : %.2lf + i%.2lf\n", root2_complex, root2_i);
printf("There are TWO COMPLEX SOLUTIONS\n");
}else{ // Zero
root_zero = (-b + sqrt(d)) / (2*a);
printf("Root : %.2lf\n", root_zero);
printf("There is ONLY ONE REAL SOLUTION\n");
}

return 0;

}

• In case d < 0 you print two identical values. Copy-paste error?
– vnp
Mar 19, 2021 at 6:56
• What result would your want if a==0 or a==0 and b==0? Mar 20, 2021 at 3:07

int main(void) is preferable, as that's clear about the number of arguments.

I don't understand why the coefficients must be integers - surely a quadratic equation can have any real coefficients?

We don't test whether the scanf() actually converted all three inputs. If we are given something that's not an integer (perhaps a different kind of number, perhaps just garbage input), then the program will proceed with incorrect data, and produce output that might be plausible, instead of a sensible error message. We need something more like:

double a, b, c;
if (scanf("%lf %lf %lf", &a, &b, &c) != 3) {
fputs("Invalid input\n", stderr);
return 1;
}


There is another case of invalid input that's not checked - if a is zero, we don't want to divide by it.

You seem to have got confused which part is real and which imaginary here:

    root1_complex = -b / (2 * a); root1_i = sqrt(-d) / (2 * a);
root2_complex = -b / (2 * a); root2_i = sqrt(-d) / (2 * a);


If we use better variable names, and reduce their scope a bit, we can make that simpler:

    double real = -b / (2 * a);
double imag = sqrt(-d) / (2 * a);


And we can do all the printing in a single call to printf:

    printf("First root : %.2f + i%.2lf\n"
"Second root : %.2lf + i%.2lf\n"
"There are TWO COMPLEX SOLUTIONS\n",
real, -imag,   real, imag);


When we know d is zero, there's really no point computing its square root:

 } else { // Zero
root_zero = -b / (2*a);


As suggested in a comment, it might also be worth computing that common part of the three expressions to outside the if/else:

const double real =  -b / a / 2;
if (d > 0) { // Positive
double root = sqrt(d) / a / 2;
⋮
} else if (d < 0) { // Negative
double imag = sqrt(-d) / a / 2;
⋮
} else { // Zero
⋮
}


Here's a lightly modified version with my suggestions applied:

#include <stdio.h>
#include <math.h>

int main(void)
{
printf("Enter a, b and c where ax² + bx + c = 0\n");
double a, b, c;
if (scanf("%lf%lf%lf", &a, &b, &c) != 3) {
fputs("Invalid input\n", stderr);
return 1;
}
if (!a) {
fputs("Quadratic term must not be zero\n", stderr);
return 1;
}

const double d = b * b - 4 * a * c;

printf("Finding the roots of %gx² + %gb + %g = 0\n", a, b, c);

const double real =  -b / a / 2;
if (d > 0) {
double root = sqrt(d) / a / 2;
printf("First Root: %.4g\n"
"Second Root: %.4g\n"
"There are TWO REAL SOLUTIONS\n",
real - root,   real + root);
} else if (d < 0) {
double imag = sqrt(-d) / a / 2;
printf("First root: %.4g + %.4gi\n"
"Second root: %.4g + %.4gi\n"
"There are TWO COMPLEX SOLUTIONS\n",
real, -imag,   real, imag);
} else { // d == 0
printf("Root: %.4g\n"
"There is ONLY ONE REAL SOLUTION\n",
real);
}
}

• Yes, very good point (excuse the pun). Mar 20, 2021 at 8:40

Here are some things that may help you improve your program. Since the other review hits most of the important parts, I'll just mention a few things.

Use standard library functions

Since C99, we have had <complex.h> which contains a number of handy complex number functions and features. Using them greatly simplifies the program:

// calculate the determinant
double d = b * b - 4 * a * c;
// calculate the roots of the equation
double complex root[2] = {
(-b + csqrt(d))/2/a,
(-b - csqrt(d))/2/a
};


Simplify printf statements

Using the above calculations, the printf statements become much simpler:

if (d > 0) {
printf("First root : %.2lf\nSecond Root : %.2lf\n"
"There are TWO REAL SOLUTIONS\n",
creal(root[0]), creal(root[1]));
} else if (d < 0) {
printf("First root : %.2lf + i%.2lf\n"
"Second Root : %.2lf + i%.2lf\n"
"There are TWO COMPLEX SOLUTIONS\n",
creal(root[0]), cimag(root[0]),
creal(root[1]), cimag(root[1]));
} else {
printf("Root : %.2lf\nThere is ONLY ONE REAL SOLUTION\n",
creal(root[0]));
}
`