//--------------------------------------------------------- // rational.h // // Declarations for a better rational class // // D Searls // Asbury College // Feb 2002 //--------------------------------------------------------- #ifndef RATIONAL_H #define RATIONAL_H #include <iostream> using namespace std; // Declaration section class rational { public: // Class constructors rational(); rational(long numer, long denom); rational(const rational &r); // Member functions private: void reduce(); public: long toInt() const; double toReal() const; void init(long numer, long denom); // Member operations public: rational operator + (const rational &r) const; rational operator - (const rational &r) const; rational operator * (const rational &r) const; rational operator / (const rational &r) const; rational& operator = (const rational &r); bool operator == (const rational &r) const; bool operator < (const rational &r) const; bool operator > (const rational &r) const; bool operator <= (const rational &r) const; bool operator >= (const rational &r) const; bool operator != (const rational &r) const; friend istream& operator >> (istream &is, rational &r); friend ostream& operator << (ostream &os, const rational &r); private: // Data members long n, d; // numerator and denominator }; #endif
//--------------------------------------------------------- // rational.cpp // // Implementation of a better rational class. // // D Searls // Asbury College // Feb 2002 //--------------------------------------------------------- #include "rational.h" #include <cmath> // Class constructors rational::rational() { n = 0; d = 1; } rational::rational(long numer, long denom) { n = numer; d = denom; reduce(); } rational::rational(const rational &r) { n = r.n; d = r.d; } // Member functions void rational::reduce() { long gcd = abs(n); long y = abs(d); long temp; // Make sure gcd is initalized as larger of two values if (gcd < y) { temp = gcd; gcd = y; y = temp; } // Find the gcd while (y != 0) { temp = gcd % y; gcd = y; y = temp; } // Reduce the fraction n = n / gcd; d = d / gcd; // Make sure denominator is positive if (d < 0) // In a reduced fraction, denominator > 0 { d = -d; n = -n; } } long rational::toInt() const { bool isNegative; double num; long intValue; isNegative = (n < 0); num = double(n)/double(d); if (isNegative) { num = -num; } intValue = long(num + 0.5); if (isNegative) { intValue = -intValue; } return intValue; } double rational::toReal() const { return double(n)/double(d); } void rational::init(long numer, long denom) { n = numer; d = denom; reduce(); } // Member operations rational rational::operator + (const rational &r) const { long numerator = n*r.d + d*r.n; long denominator = d*r.d; rational sum(numerator, denominator); return sum; } rational rational::operator - (const rational &r) const { long numerator = n*r.d - d*r.n; long denominator = d*r.d; rational diff(numerator, denominator); return diff; } rational rational::operator * (const rational &r) const { long numerator = n*r.n; long denominator = d*r.d; rational prod(numerator, denominator); return prod; } rational rational::operator / (const rational &r) const { long numerator = n*r.d; long denominator = d*r.n; rational quotient(numerator, denominator); return quotient; } rational& rational::operator = (const rational &r) { n = r.n; d = r.d; return *this; } bool rational::operator == (const rational &r) const { return (n*r.d == d*r.n); } bool rational::operator < (const rational &r) const { return (n*r.d < d*r.n); } bool rational::operator > (const rational &r) const { return (n*r.d > d*r.n); } bool rational::operator <= (const rational &r) const { return (n*r.d <= d*r.n); } bool rational::operator >= (const rational &r) const { return (n*r.d >= d*r.n); } bool rational::operator != (const rational &r) const { return (n*r.d != d*r.n); } istream& operator >> (istream &is, rational &r) { char slash; is >> r.n; // Read the numerator is >> slash; // Read the divide symbol is >> r.d; // Read the denominator r.reduce(); return is; } ostream& operator << (ostream &os, const rational &r) { os << r.n << '/' << r.d; return os; }