5
\$\begingroup\$

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;
    
}
\$\endgroup\$
2
  • 3
    \$\begingroup\$ In case d < 0 you print two identical values. Copy-paste error? \$\endgroup\$
    – vnp
    Mar 19, 2021 at 6:56
  • \$\begingroup\$ What result would your want if a==0 or a==0 and b==0`? \$\endgroup\$ Mar 20, 2021 at 3:07

2 Answers 2

6
\$\begingroup\$

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);
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Yes, very good point (excuse the pun). \$\endgroup\$ Mar 20, 2021 at 8:40
5
\$\begingroup\$

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]));
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.