/*************************************************/
// R. A. Hillyard
// rational04.cpp
// November 2001
//
// class with constructors, friend functions and operator overloading
// use of const keyword for reference parameters and functions
/*************************************************/

#include <iostream>

using namespace std;

class Rational
  {
  public :
    friend bool operator ==(const Rational& f1, const Rational& f2);
    friend Rational operator -(const Rational& f1, const Rational& f2);
    friend Rational subtract(const Rational& f1, const Rational& f2);  
    friend int gcd(int x, int y);   

    //constructors
    Rational();
    Rational(int top);
    Rational(int top, int bottom);
    
    //accessor functions
    void output() const;
    int getTop() const;
    int getBottom() const;
    
    //mutator functions
    void setTop(int t);
    void setBottom(int b);
  
  private:
    int top;
    int bottom;  
  };
/********************************************************/
bool operator ==(const Rational& f1, const Rational& f2)
  { return((f1.top * f2.bottom) == (f1.bottom * f2.top ));  }
/********************************************************/
Rational operator -(const Rational& f1, const Rational& f2)
  {
  int factor;
  int t = f1.top * f2.bottom - f2.top * f1.bottom;
  int b = f1.bottom * f2.bottom;

  factor = gcd(t,b);
  Rational temp(t/factor,b/factor);
  return temp;
  }
/********************************************************/
Rational subtract(const Rational& f1, const Rational& f2)
  {
  int factor;
  //new top and bottom
  int t1 = (f1.top * f2.bottom) - (f2.top * f1.bottom);
  int b1 = (f1.bottom * f2.bottom);

  //reduce fraction
  factor = gcd(t1,b1);
  Rational temp(t1/factor,b1/factor);
  return temp;
  }  
/********************************************************/
int gcd(int x, int y)
  {
  int c;     //store remainder
  
  while( (c = x%y) != 0 )
    {
    x = y;
    y = c;
    }//end while

  return y;  
  }//end of gcd
/********************************************************/
Rational::Rational()
  {
  top = 0;
  bottom = 1;
  }
/********************************************************/
Rational::Rational(int t)
  {
  top = t;
  bottom = 1;
  }
/********************************************************/
Rational::Rational(int t, int b)
  {
  top = t;
  bottom = b;
  }
/********************************************************/
int Rational::getTop() const
  {  return top;  }
/********************************************************/
int Rational::getBottom() const
  {  return bottom;  }
/********************************************************/
void Rational::output() const
  {  cout << top << "/" << bottom;  }
/********************************************************/
void Rational::setTop(int t)
  {  top = t;  }
/********************************************************/
void Rational::setBottom(int b)
  {  bottom = b;  }
/********************************************************/

/********************************************************/
int main( void )
  {
  Rational f1(2,6);
  Rational f2(1,3);
  Rational f3;
  Rational f4;

  f3 = Rational(7,9);
  
  cout << "To start your fractions are: ";
  f1.output();  cout << " ";
  f2.output();  cout << " ";
  f3.output();  cout << endl;
  
  f1 = Rational(3,6);
  f2 = Rational(50,100);
  f4 = f1 - f3;
 
  cout << "After your fractions are: ";
  f1.output();  cout << " ";
  f2.output();  cout << " ";
  f3.output();  cout << " ";
  f4.output();  cout << endl;

  if(f1 == f2)
    cout << "f1 and f2 are equal\n";
  else
    cout << "f1 and f2 are not equal\n";
    
  return 0;
  }
/*************Program Output*********************
To start your fractions are: 2/6 1/3 7/9
After your fractions are: 3/6 50/100 7/9 -5/18
f1 and f2 are equal
*/