/******************************* 
 File <lab6_func.c> 
 M2120-Fall'05-Lab 6 (Follow-up) 
 Author: Sergey Sadov 
 Date: Monday Oct.17 2005 
 Solution of quadratic equation 
 Version with programmer-defined functions
********************************/

/* To complile:  gcc -lm  lab6_func.c */

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

/* #define _DEBUG -- commented in the version with interactive input */  

/* Declaration of function that solves linear equation u*x+v=0 */
  double linRoot(double u, double v);

/* Declaration of function that finds roots of quadratic eq. assuming
 the discriminant is already computed:
  x1=(-b-sqrt(D))/(2*a), x2=(-b+sqrt(D))/(2*a)
*/
  void quadRoots(double a, double b, double D, double* X1, double* X2);
  /* Note: need asterisks before x1,x2, since these are addresses of
     values to be passed back to the caller */

int main()
{
  double a,b,c; /* Coefficients in equation */
  double D; /* the discriminant */
  double x1,x2; /* roots */
  
  #ifdef _DEBUG
    a=7; /* Sample initialization: 7(x^2+5x+6)=0 */ 
    b=-35;
    c=42;  
    /* Roots: 2 and 3 */
  #else
    printf("Please type in the coefficients of quadratic equation\n: a=");
    scanf("%lf", &a);
    printf(" b=");
    scanf("%lf", &b);
    printf(" c=");
    scanf("%lf", &c);
 #endif
  
  printf("Solving a quadratic %4.2lfx^2+%4.2lfx+%4.2lf=0 \n",a,b,c);
  /* Apropos %4.2lf: see p.52 in Bronson (Format Modifiers) */ 
  
  if (a!=0)
  {
    printf("Main case: a!=0\n");
    D=b*b-4*a*c;
    printf("D=%lf\n",D);
    if (D<0)
    {
      printf("D<0, no roots\n");
      return(0);  /* no numbers to print, so finish immediately */
    }
    else /* if D>=0 */
    {
      printf("D>=0, proceeding...\n");
      /* These operations are now delegated to a separate function
         x1=(-b-sqrt(D))/(2.0*a);
         x2=(-b+sqrt(D))/(2.0*a);
       */
       quadRoots(a,b,D,&x1,&x2); 
       /* Need ampersands before x1, x2 here! But not in C++ version! */
    }
  }
  else /* if a==0 */
  {
    printf("An equation of degree less than 2: a==0\n");
    if (b==0) /* Note: double == meaning "if b is equal to 0" */
    {
      if (c==0)
        printf("Answer: any x\n");
      else /* c!=0 */
        printf("Answer: no roots\n");
      return(0); /* no numbers to print, so finish immediately */
    }
    else /* if b!=0 */
    {
     /* old version: inline calculation x1=-c/b; */
     /* Now using special function: */
      x1=linRoot(b,c);  
      /* x2 remains unitialized in this case */ 
    }
  }
  
  /* x1=89; x2=-36; -- these assignments were used at the initial stage
   of work, just to check that the next printf compiles and works correctly.*/
  
  printf("Answer: x1=%lf, x2=%lf\n", x1,x2);
   /* One remaining deficiency in this program: in the case a==0  
      it still prints two roots, though the 2nd one is a random value. */

  printf("Done\n");
  
  return(0);
}

/*----------------------------------------------------------*/
/* Implementation of programmer-defined functions           */

double linRoot(double u, double v)
{
  return (-v/u);
}

/*----------------------------------------------------------*/
void quadRoots(double a, double b, double D, double* X1, double* X2)
{
   double sqrtD; /* to avoid calculating sqrt(D) twice */
   sqrtD=sqrt(D);
   (*X1)=(-b-sqrtD)/(2.0*a);
   (*X2)=(-b+sqrtD)/(2.0*a);
}
/* EOF */

