// // See rationals_v2.h for documentation // #include #include "rationals_v2.h" // class definition // -------- implementation of RationalNum class -------- // ---- prototypes for "helper functions" ---- // function to compute greatest common divisor // precondition: m, n are positive numbers // postcondition: return value is the greatest common divisor of m, n int gcd(int m, int n); // ---- function definitions ---- // ---- constructors ---- RationalNum::RationalNum(const int n, const int d) { numerator = n; denominator = d; } // ---- member functions ---- void RationalNum::reduce(void) { int divisor; if (denominator == 0) numerator = 1; else if (numerator == 0) denominator = 1; else { if (denominator < 0) { denominator *= -1; numerator *= -1; } divisor = gcd(abs(numerator), denominator); numerator /= divisor; denominator /= divisor; } return; } // arithmetic operations RationalNum& RationalNum::operator+=(const RationalNum q) { int new_n = numerator*q.denominator + q.numerator*denominator; int new_d = denominator*q.denominator; numerator = new_n; denominator = new_d; reduce(); return *this; } RationalNum& RationalNum::operator-=(const RationalNum q) { int new_n = numerator*q.denominator - q.numerator*denominator; int new_d = denominator*q.denominator; numerator = new_n; denominator = new_d; reduce(); return *this; } RationalNum& RationalNum::operator*=(const RationalNum q) { numerator *= q.numerator; denominator *= q.denominator; reduce(); return *this; } RationalNum& RationalNum::operator/=(const RationalNum q) { numerator *= q.denominator; denominator *= q.numerator; reduce(); return *this; } // ---- friend functions ---- // input/output istream& operator>>(istream& iStr, RationalNum& r) { int n, d; char c; iStr >> n >> c >> d; if (iStr && (c == '/')) { r.numerator = n; r.denominator = d; } else { iStr.clear(ios::badbit); } return iStr; } ostream& operator<<(ostream& oStr, const RationalNum r) { oStr << r.numerator << "/" << r.denominator; return oStr; } // comparisons bool operator==(const RationalNum p, const RationalNum q) { return (p.numerator*q.denominator) == (q.numerator*p.denominator); } bool operator<(const RationalNum p, const RationalNum q) { return (p.numerator*q.denominator) < (q.numerator*p.denominator); } bool operator>(const RationalNum p, const RationalNum q) { return (p.numerator*q.denominator) > (q.numerator*p.denominator); } bool operator<=(const RationalNum p, const RationalNum q) { return (p.numerator*q.denominator) <= (q.numerator*p.denominator); } bool operator>=(const RationalNum p, const RationalNum q) { return (p.numerator*q.denominator) >= (q.numerator*p.denominator); } bool operator!=(const RationalNum p, const RationalNum q) { return (p.numerator*q.denominator) != (q.numerator*p.denominator); } // arithmetic operators RationalNum operator+(const RationalNum p, const RationalNum q) { RationalNum r = RationalNum( p.numerator*q.denominator + q.numerator*p.denominator, p.denominator*q.denominator); r.reduce(); return r; } RationalNum operator-(const RationalNum p, const RationalNum q) { RationalNum r = RationalNum( p.numerator*q.denominator - q.numerator*p.denominator, p.denominator*q.denominator); r.reduce(); return r; } RationalNum operator*(const RationalNum p, const RationalNum q) { RationalNum r = RationalNum(p.numerator*q.numerator, p.denominator*q.denominator); r.reduce(); return r; } RationalNum operator/(const RationalNum p, const RationalNum q) { RationalNum r = RationalNum(p.numerator*q.denominator, p.denominator*q.numerator); r.reduce(); return r; } RationalNum operator-(const RationalNum p) { RationalNum r = RationalNum(-p.numerator, p.denominator); r.reduce(); return r; } // ---- "helper functions" ---- int gcd(int m, int n) // use Euclid's algorithm for finding greatest common divisor // depends on two observations: // if m is a multiple of n, gcd(m, n) == n // otherwise, can write m = nt + r, and gcd(m, n) == gcd(n, r) { int r; // ensure that m >= n if (m < n) { int temp = m; m = n; n = temp; } do { r = m % n; m = n; n = r; } while (r != 0); return m; }