/*
        Module Math utils
*/

#include <math.h>
   
static double absd(double x) {
   if(x<0)
      return(-x);
   else
      return(x);
}

static double roundd(double x) {
double Ent,Rat;

   Rat = modf(x,&Ent);

   if(Rat < 0.5)
      return(Ent);
   else
      return(Ent+1);
}

int min(int x,int y) {
   if(x<y)
      return(x);
   else
      return(y);
}

double mind(double x,double y) {
   if(x<y)
      return(x);
   else
      return(y);
}

int max(int x,int y) {
   if(x>y)
      return(x);
   else
      return(y);
}

double maxd(double x,double y) {
   if(x>y)
      return(x);
   else
      return(y);
}


int pgcd(int a,int b) {
 int p;
 if ((a==1) || (b==1)) return(1);
 if (a<b) {
   p=b;
   b=a;
   a=p;
 } /* Now a is the highest */
 while ((b>1) && (a!=b)) {
  p=b; b=a%b; a=p;
 }
 if (b==1) return(1); else return(a);
}

void red_frac(int *a,int *b) {
  int p=pgcd(*a,*b);
  *a=(*a)/p;
  *b=(*b)/p;
}  

void red_frac_arrond(int *Num,int *Den,int MaxDen) {
 double Frac;
 int RedNum=1 , RedDen;
 int BestDen=1 , BestNum=1;
   
   Frac = (double)*Num / (double)*Den;
   for(RedDen = 2; RedDen < MaxDen ; RedDen++) {        
      RedNum = (int)roundd((double)RedDen * Frac);
      if( absd( ( (double)RedNum / (double)RedDen ) - Frac ) 
         < absd( ( (double)BestNum / (double)BestDen ) - Frac ) ) {
         BestNum = RedNum;
         BestDen = RedDen;
      }
   }
   (*Num)=BestNum;
   (*Den)=BestDen;
}
