/* ------------------------------------------------------------------------ ** Figure 12.10: Returning three results. ** Figure 12.11: The quadratic root function. ** ------------------------------------------------------------------------ ** Solve a quadratic equation with any coefficients a, b, and c. Test for ** degenerate equations and account for single roots and complex roots. */ #include "tools.c" #define EPS 1e-6 typedef enum { NONE, LINEAR, SINGLE, REAL, COMPLEX } root_type; root_type solve( double a, double b, double c, double* rp1, double* rp2 ); bool iszero( double x ) { return fabs( x ) < EPS; } void main( void ) { double a, b, c; /* Coefficients of the equation. */ double r1, r2; /* Roots of the equation. */ root_type n_roots; /* How many roots the equation has. */ banner(); puts( " Find the roots of a*x^2 + b*x + c = 0" ); printf( " Enter the values of a, b, and c: " ); scanf( "%lg%lg%lg", &a, &b, &c ); printf( "\n The equation is %.3g *x^x + %.3g *x + %.3g = 0\n", a, b, c ); n_roots = solve( a, b, c, &r1, &r2 ); switch (n_roots) { case NONE: printf( "\n Degenerate equation -- no roots\n" ); break; case LINEAR: printf( "\n Linear equation -- root at -c/b = %.3g\n", r1 ); break; case SINGLE: printf( "\n Single real root at x = %.3g \n", r1 ); break; case REAL: printf( "\n The real roots are x = %.3g and %.3g \n", r1, r2 ); break; case COMPLEX: printf( "\n The roots are x = %.3g + %.3g i and " "x = %.3g - %.3g i \n", r1, r2, r1, r2 ); } bye(); } /* ---------------------------------------------------------------------------- ** Find the root or roots of a quadratic equation. */ root_type solve( double a, double b, double c, double* rp1, double* rp2 ) { double d, two_a, sroot; /* Working storage. */ if (iszero( a ) && iszero( b )) return NONE; /* Degenerate cases. */ if (iszero( a )) { *rp1 = -c / b; return LINEAR; } two_a = 2 * a; d = b * b - 4 * a * c; /* discriminant of equation. */ if (iszero( d )) { /* There is only one root. */ *rp1 = -b / two_a; return SINGLE; } sroot = sqrt( fabs( d ) ); /* fabs is floating point absolute value. */ if (d > EPS) { /* There are 2 real roots. */ *rp1 = -b / two_a + sroot / two_a; *rp2 = -b / two_a - sroot / two_a; return REAL; } else { /* There are 2 complex roots. */ *rp1 = -b / two_a; *rp2 = sroot / two_a; return COMPLEX; } }