// fraction.h // =================== // Kole Kantner // CAE Homework #5 // Fraction class // The Program fraction declares a class of type Fraction that contains two // private members numer and denom corresponding to numerator and denominator. // // The following public member functions are declared to operate on the // class Fraction: // default and initializer constructors; // algebraic operators +, -, * and /; // conversion to decimal equivalent; // simplification; // output to write fractions in form a/b; // equality test. // // The main section declares several fractions and tests the member functions. // Class declaration class Fraction { public: Fraction (); Fraction (int num, int den); double float_equiv (); void simplify(); void write(); int operator== (Fraction frac); Fraction& operator= (Fraction rhs); Fraction operator+ (Fraction frac); Fraction operator- (Fraction frac); Fraction operator* (Fraction frac); Fraction operator/ (Fraction frac); private: int numer; int denom; }; ostream& operator<< (ostream& out, Fraction frac); istream& operator>> (istream& in, Fraction& frac); // declaration for a greatest common divisor function. // useful for simplification. int find_gcd (int a, int b); // Definition of Member Functions // Constructors Fraction::Fraction() // Default constructor { numer = 0; denom = 1; } Fraction::Fraction (int num, int den) // Constructor with initialization { numer = num; denom = den; } // Miscelaneous Member Functions: output, type conversion, simplification // and test for equality. void Fraction::write () // Write a fraction in the form a/b { if (denom == 1) cout << numer; // Write the fraction a/1 as a else cout << numer << "/" << denom; } double Fraction::float_equiv() // Convert a fraction to its decimal equivalent { return(double(numer) / double(denom)); } // Simplify the fraction by dividing both numerator and denominator by the gcd void Fraction::simplify() { int fraction_gcd = find_gcd(numer, denom); numer = numer / fraction_gcd; denom = denom / fraction_gcd; if (denom < 0) { numer = - numer; // For negative fractions make the numerator negative denom = - denom; // so the "-" leads the fraction when written. } } // Test for equality of two fractions. // Simplify fractions so that equality can be tested by equality of // numerators and denominators. // Use temporary fractions frac1 and frac2 so simplification doesn't modify // original fractions. int Fraction::operator== (Fraction frac) { Fraction frac1(numer, denom); Fraction frac2(frac.numer, frac.denom); frac1.simplify(); frac2.simplify(); return((frac1.numer == frac2.numer) && (frac1.denom == frac2.denom)); } Fraction& Fraction::operator= (Fraction rhs) { numer = rhs.numer; denom = rhs.denom; return *this; } ostream& operator<< (ostream& out, Fraction frac) { if (frac.denom == 1) out << frac.numer; // Write the fraction a/1 as a else out << frac.numer << "/" << frac.denom; return out; } ostream& operator>> (istream& in, Fraction& frac) { cout << "\n Input fraction numerator and denominator:"; in >> frac.numer; in >> frac.denom; return in; } // Algebraic operator Member Functions. // The results of the following fraction operators +, -, * and / are all // simplified after the operation is performed to aid in readability, and // to reduce the size of the individual numbers to avoid overflow. // In order to perform addition of two fractions, both denominators must // be the same. Since the result will be simplified anyway, an easy way to // make both denominators identical is to multiply each fraction's numerator // and denominator by the other fraction's original denominator. Fraction Fraction::operator+ (Fraction frac) // Add two fractions { int num_result = (numer * frac.denom) + (denom * frac.numer); int den_result = denom * frac.denom; Fraction result(num_result, den_result); result.simplify(); return(result); } Fraction Fraction::operator- (Fraction frac) // Take the difference { int num_result = (numer * frac.denom) - (denom * frac.numer); int den_result = denom * frac.denom; Fraction result(num_result, den_result); result.simplify(); return(result); } Fraction Fraction::operator* (Fraction frac) // Multiply two fractions { int num_result = numer * frac.numer; int den_result = denom * frac.denom; Fraction result(num_result, den_result); result.simplify(); return(result); } // Find the quotient of two fractions. A divide-by-zero error will result // if the second fraction is zero, as regular division does. // To avoid truncation errors, do division by multiplying the numerator // fraction by the inverted denominator fraction. Fraction Fraction::operator/ (Fraction frac) { int num_result = numer * frac.denom; int den_result = denom * frac.numer; Fraction result(num_result, den_result); result.simplify(); return(result); } // Utilities // The function find_gcd determines the greatest common divisor of two // variables a and b using Euclid's algorithm. // Function find_gcd requires that b not equal zero. // // Explanation of Euclid's algorithm: // Initially, a = numerator and b = denominator. Suppose that, at the // beginning of an iteration, a and b have certain values, and let a' and b' // be their values at the beginning of the next iteration. Euclid's // algorithm works by assigning b to a' and a % b to b'. The loop // repeats until b is zero, at which time a is the greatest common divisor. int find_gcd (int a, int b) { int remainder; while (b != 0) { remainder = a % b; a = b; // a' gets b b = remainder; // b' gets a % b } return(a); }