#include "Rational.h" #include using namespace std; namespace { // n is guaranteed non-negative int gcd1( int n, int m ) { if( n % m == 0 ) return m; else return gcd1( m, n % m ); } int gcd( int m, int n ) { if( m > 0 ) return gcd1( n, m ); else return gcd1( n, -m ); } } void Rational::fixSigns( ) { if( denom < 0 ) { denom = -denom; numer = -numer; } } void Rational::reduce( ) { int d = 1; if( denom != 0 && numer != 0 ) d = gcd( numer, denom ); if( d > 1 ) { numer /= d; denom /= d; } } const Rational & Rational::operator+=( const Rational & rhs ) { numer = numer * rhs.denom + rhs.numer * denom; denom = denom * rhs.denom; reduce( ); return *this; } const Rational & Rational::operator-=( const Rational & rhs ) { numer = numer * rhs.denom - rhs.numer * denom; denom = denom * rhs.denom; reduce( ); return *this; } const Rational & Rational::operator*=( const Rational & rhs ) { int newNumer = numer * rhs.numer; int newDenom = denom * rhs.denom; numer = newNumer; denom = newDenom; reduce( ); return *this; } const Rational & Rational::operator/=( const Rational & rhs ) { int newNumer = numer * rhs.denom; int newDenom = denom * rhs.numer; numer = newNumer; denom = newDenom; fixSigns( ); reduce( ); return *this; } Rational operator+( const Rational & lhs, const Rational & rhs ) { Rational answer( lhs ); // Initialize answer with lhs answer += rhs; // Add the second operand return answer; // Return answer by copy } Rational operator-( const Rational & lhs, const Rational & rhs ) { Rational answer( lhs ); // Initialize answer with lhs answer -= rhs; // Subtract the second operand return answer; // Return answer by copy } Rational operator*( const Rational & lhs, const Rational & rhs ) { Rational answer( lhs ); // Initialize answer with lhs answer *= rhs; // Multiply the second operand return answer; // Return answer by copy } Rational operator/( const Rational & lhs, const Rational & rhs ) { Rational answer( lhs ); // Initialize answer with lhs answer /= rhs; // Divide the second operand return answer; // Return answer by copy } bool operator==( const Rational & lhs, const Rational & rhs ) { return (lhs - rhs).isZero( ); } bool operator!=( const Rational & lhs, const Rational & rhs ) { return (!lhs - rhs).isZero( ); } bool operator<( const Rational & lhs, const Rational & rhs ) { return (lhs - rhs).isNegative( ); } bool operator>( const Rational & lhs, const Rational & rhs ) { return (lhs - rhs).isPositive( ); } bool operator<=( const Rational & lhs, const Rational & rhs ) { return !(lhs - rhs).isPositive( ); } bool operator>=( const Rational & lhs, const Rational & rhs ) { return (!lhs - rhs).isNegative( ); } const Rational & Rational::operator++( ) // Prefix form { numer += denom; return *this; } Rational Rational::operator++( int ) // Postfix form { Rational tmp = *this; numer += denom; return tmp; } const Rational & Rational::operator--( ) // Prefix form { numer -= denom; return *this; } Rational Rational::operator--( int ) // Postfix form { Rational tmp = *this; numer -= denom; return tmp; } bool Rational::operator!( ) const { return !numer; } const Rational & Rational::operator+( ) const { return *this; } Rational Rational::operator-( ) const { return Rational( -numer, denom ); } istream & operator>>( istream & in, Rational & value ) { int num; int den = 1; in >> num; char ch; in.get( ch ); if( !in.eof( ) ) { if( ch == '/' ) in >> den; else in.putback( ch ); } value = Rational( num, den ); return in; } void Rational::print( ostream & out ) const { if( denom != 0 ) { out << numer; if( denom != 1 ) out << '/' << denom; } // Messy code for denom == 0 else if( numer == 0 ) out << "indeterminate"; else { if( numer < 0 ) out << '-'; out << "infinity"; } } ostream & operator<<( ostream & out, const Rational & value ) { value.print( out ); return out; }