#include #include using namespace std; void swap(int& a, int& b) { int temp = a; a = b; b = temp; } int gcd(int a, int b){ assert (a || b); if ( a < 0 ) a = -a; if ( b < 0 ) b = -b; if ( a < b ) swap(a,b); if ( b == 0 ) return a; int r = a%b; if (r == 0) return b; else return gcd(b, r); // Check it. } class Fraction{ public: Fraction(int, int); // Constructor. Fraction():n(0),d(1){} // Default Constructor. int top() const { return n; } // Accessor. int bot() const { return d; } // Accessor. // const Fraction& operator=( const Fraction& ); // Automatically generated --- no need to implement here. const Fraction& operator+=( const Fraction& ); // Mutator. istream& get(istream&); // Input. ostream& put(ostream&) const; // Output. private: // Clients cannot touch these. int n, d; }; istream& operator>>( istream& is, Fraction& f){ f.get(is); return is; } ostream& operator<<( ostream& os, const Fraction& f){ f.put(os); return os; } Fraction::Fraction(int n0, int d0){ assert (d0); if (d0 < 0) { // For definiteness, always store d0 = -d0; // the denominator as positive. n0 = -n0; } int g = gcd(n0,d0); n = n0/g; d = d0/g; } istream& Fraction::get(istream& is){ // Input. int n0,d0; // temporaries. is >> n0; char ch; if (is){ is >> ch; assert(ch == '/'); } if (is) is >> d0; // Enforce format. if (is) { int g = gcd(n0,d0); n = n0/g; d = d0/g; } return is; } ostream& Fraction::put(ostream& os) const { // Output. os << n << '/' << d; return os; } Fraction operator+(const Fraction& f, const Fraction& g ){ if ( f.top() == 0 ) return g; else if ( g.top() == 0 ) return f; else return Fraction( f.top()*g.bot() + f.bot()*g.top(), f.bot()*g.bot() ); } const Fraction& Fraction::operator+=(const Fraction& g ){ int n0 = n*g.d + d*g.n; int d0 = d*g.d ; int fac = gcd(n0,d0); n = n0/fac; d = d0/fac; return *this; } Fraction operator-(const Fraction& f){ return Fraction(-f.top(), f.bot()); } Fraction operator-(const Fraction& f, const Fraction& g ){ if ( f.top() == 0 ) return -g; else if ( g.top() == 0 ) return f; else return Fraction( f.top()*g.bot() - f.bot()*g.top(), f.bot()*g.bot() ); } Fraction operator*(const Fraction& f, const Fraction& g ){ return Fraction( f.top()*g.top(), f.bot()*g.bot() ); } Fraction operator/(const Fraction& f, const Fraction& g ){ return Fraction( f.top()*g.bot(), f.bot()*g.top() ); } bool operator==( const Fraction& f, const Fraction& g ){ return (f.top()==g.top()) && (f.bot()==g.bot()); } bool operator!=( const Fraction& f, const Fraction& g ){ return !(f==g); } bool operator<=( const Fraction& f, const Fraction& g ){ return (f.top()*g.bot() <= f.bot()*g.top()); } bool operator>=( const Fraction& f, const Fraction& g ){ return (f.top()*g.bot() >= f.bot()*g.top()); } bool operator>( const Fraction& f, const Fraction& g ){ return (f.top()*g.bot() > f.bot()*g.top()); } bool operator<( const Fraction& f, const Fraction& g ){ return (f.top()*g.bot() < f.bot()*g.top()); } int main(){ // Test driver. Fraction f, g, h; cout << "Enter two fractions, separated by spaces only: "; f.get(cin); g.get(cin); cout << "f = "; f.put(cout); cout << " g = "; g.put(cout); cout << endl; cout << "f + g = "; h = f+g; h.put(cout); cout << endl; cout << "f - g = "; h = f-g; h.put(cout); cout << endl; cout << "f * g = "; h = f*g; h.put(cout); cout << endl; cout << "f / g = "; h = f/g; h.put(cout); cout << endl << endl; if ( f == g ) cout << " f == g.\n"; else if ( f < g ) cout << " f < g.\n"; else if ( f > g ) cout << " f > g.\n"; else cout << "Error in comparing f and g.\n"; f += g; cout << "\nAfter f+=g, f = " << f << ".\n"; return 0; } /* Sample I/O. Enter two fractions, separated by spaces only: 24/56 56/96 f = 3/7 g = 7/12 f + g = 85/84 f - g = -13/84 f * g = 1/4 f / g = 36/49 f < g. After f+=g, f = 85/84. */