/*
 *  ========================================================================
 *  Solve Quadratic Equations : Coefficients are read in from keyboard
 *                            : Roots of Quadratic are printed to screen.
 *                                                                     
 *  Note : Naive implementation of quadratic equation solver. This algorithm
 *         does not take into account possible loss of accuracy when two
 *         floating point numbers of almost equal size are subtracted.
 *                                                                     
 *  Copyright (C) 1998 by Mark Austin and David Chancogne.
 *                                                                     
 *  This software is provided "as is" without express or implied warranty.
 *  Permission is granted to use this software on any computer system,
 *  and to redistribute it freely, subject to the following restrictions:
 * 
 *  1. The authors are not responsible for the consequences of use of
 *     this software, even if they arise from defects in the software.
 *  2. The origin of this software must not be misrepresented, either
 *     by explicit claim or by omission.
 *  3. Altered versions must be plainly marked as such, and must not
 *     be misrepresented as being the original software.
 *  4. This notice is to remain intact.
 * 
 *  Written by : Mark Austin 
 *  ========================================================================
 */

#include <stdio.h>   /* Standard Input/Output function declarations */
#include <stdlib.h> 
#include <math.h>    /* Math functions, such as sqrt(x).            */

/* Function declarations */

float discriminant( float , float , float );
void  quadratic ( float , float , float );

/* Main program for quadratic equation solver */

int main( void ) {
float   fA, fB, fC;          /* Coefficients for quadratic equation */

   /* [a] : Print welcome message */

   printf("Welcome to the Quadratic Equation Solver (Version 1)\n");
   printf("====================================================\n");

   /* [b] : Prompt user for coefficients of quadratic equation */

   printf("Please enter coefficients for equation a.x^2 + b.x + c\n");
   printf("Enter coefficient a : ");
   scanf("%f%*c", &fA);
   printf("Enter coefficient b : ");
   scanf("%f%*c", &fB);
   printf("Enter coefficient c : ");
   scanf("%f%*c", &fC);

   /* [c] : Print quadratic equation to screen */

   printf("Equation you have entered is : %g.x^2 + %g.x + %g\n", fA, fB, fC);

   /* [d] : Compute roots of quadratic equation */

   quadratic ( fA, fB, fC );
   return (0);
}

/*
 *  ===========================================================
 *  quadratic() : Compute roots to Quadratic Equations
 *
 *  Input  : float fA -- Coefficient "fA" in Quadratic equation
 *           float fB -- Coefficient "fB" in Quadratic equation
 *           float fC -- Coefficient "fC" in Quadratic equation
 *  Output : void
 *  ===========================================================
 */

void quadratic ( float fA, float fB, float fC ) {
float fRoot1, fRoot2;      /* Real roots 1 and 2 of quadratic equation */
float  fDiscriminant;      /* Discriminant of quadratic                */

   /* [a] : Compute roots of simplified equations : fA equals zero */

   if(fA == 0 && fB == 0) {
      printf("Cannot solve Extremely degenerate equation " );
      printf("%14.8g = 0.0\n", fC );
      exit (1);
   }

   if(fA == 0 && fB != 0) {
      fRoot1 = - fC/fB;
      printf("Degenerate root : Root = %14.8g\n", fRoot1 );
      exit (1);
   }

   /* [b] : Compute roots of quadratic equation : fA not equal to zero */

   fDiscriminant = discriminant( fA, fB, fC );
   if(fDiscriminant >= 0) { /* Case for two real roots */

      fRoot1 = -fB/2.0/fA - sqrt( fDiscriminant )/2.0/fA;
      fRoot2 = -fB/2.0/fA + sqrt( fDiscriminant )/2.0/fA;

      printf("Two real roots : Root1 = %14.8g\n", fRoot1 );
      printf("               : Root2 = %14.8g\n", fRoot2 );
   } else {                   /* Case for complex roots */

      printf("Two complex roots : Root1 = %14.8g + %14.8g i\n", -fB/2.0/fA,
              sqrt( -fDiscriminant )/2.0/fA);
      printf("                  : Root2 = %14.8g + %14.8g i\n", -fB/2.0/fA,
             -sqrt( -fDiscriminant )/2.0/fA);
   }
}

/*
 *  ===========================================================
 *  discriminant() : Compute discriminant of quadratic equation
 *
 *  Input  : float fA -- Coefficient "fA" in quadratic equation
 *           float fB -- Coefficient "fB" in quadratic equation
 *           float fC -- Coefficient "fC" in quadratic equation
 *  Output : float    -- Numerical value of discriminant.
 *  ===========================================================
 */

float discriminant( float fA, float fB, float fC ) {
float fDiscriminant;

      fDiscriminant = fB*fB - 4.0*fA*fC;
      return(fDiscriminant);
}
