//Rationals.cpp #include"Rationals.h" Rational::Rational() { numerator=1; denominator=1; }//end default constructor //******************* Rational::Rational(int n, int d) { set(n,d); //set does all the work, why repeat the code here? } //******************* bool Rational::set(int n, int d) //returns false if you try to set // denominator to 0 { numerator = n; if (d==0) { denominator = 1; cout << "\nBad denominator.\n"; return false; } //end then clause //Only get here if denominator nonzero if (d<0) //negative signs only in numerator { numerator=-numerator; denominator=-d; } else //d>0 denominator=d; int factor=gcd(numerator,denominator); numerator=numerator/factor; denominator=denominator/factor; return true; }//end bool Rational::set(int n, int d) //******************* int Rational::getNumerator() { return numerator; } //end getNumerator() //******************* int Rational::getDenominator() { return denominator; } // end getDenominator //******************* Rational Rational::operator+(Rational right) { int n, d; n=numerator*right.denominator + denominator*right.numerator; d=denominator*right.denominator; Rational answer(n,d); return answer; } // end operator+(Rational right) //******************* Rational Rational::operator-( Rational right) { int n, d; n=numerator*right.denominator - denominator*right.numerator; d=denominator*right.denominator; Rational answer(n,d); return answer; } // end operator-(Rational right) Rational Rational::operator*(Rational right) { int n=numerator * right.numerator; int d=denominator * right.denominator; Rational answer(n,d); return answer; }//end Rational::operator*(Rational right) Rational Rational::operator/(Rational right) { if (right.numerator==0) { cout << "\n**Division by Zero**\n"; Rational answer=*this; return answer; } //not dividing by zero int n=numerator * right.denominator; int d=denominator * right.numerator; Rational answer(n,d); return answer; }//end Rational::operator/(Rational right) //******************* bool Rational::operator>(Rational right) { return (numerator*right.denominator>denominator*right.numerator); }//end Rational::operator>(Rational right) //******************* bool Rational::operator==(Rational right) { return(numerator*right.denominator == denominator*right.numerator); } //end Rational::operator==(Rational right) //******************* bool Rational::operator==(int right) { return ( numerator == right * denominator ); } //******************* ostream& Rational::printquotient(ostream & outfile) { outfile << numerator << '/' << denominator; return outfile; } //******************* ostream& Rational::printdecimal(ostream & outfile) { outfile << static_cast(numerator)/denominator; return outfile; } // end Rational::printdecimal(ostream & outfile) //******************* istream& Rational::read(istream & infile) { int n,d; char c; infile >> n >> c >> d; set(n,d); return infile; } // end Rational::read(istream & infile) //******************* int Rational::gcd(int & n, int & d) //given a and b, it will compute their GCD //and divide them both by the GCD { int q, r, b; int a=abs(n); b=d; q=a/b; //integer division r=a-b*q; //remaider int rold=b; while (r!=0) { a=b; b=r; q=a/b; rold=r; r=a-b*q; }//end while //rold is the gcd return rold; } //******************* bool operator==(int left, Rational right) { return(right==left); } //******************* //#define RATIONAL_TEST #ifdef RATIONAL_TEST void testSetAndEuclid(Rational & r) { //test set and Euclid cout << "\nRelatively prime: "; r.set(5,7); cout << "r is "; r.printquotient(cout); cout << "\nPositive, common factor: "; r.set(18,24); cout << "r is "; r.printquotient(cout); cout << "\nNegative numerator, common factor: "; r.set(-18,24); cout << "r is "; r.printquotient(cout); cout << "\nNegative denominator, common factor: "; r.set(18,-24); cout << "r is "; r.printquotient(cout); cout << "\nNegative both, common factor: "; r.set(-18,-24); cout << "r is "; r.printquotient(cout); cout << "\nZero denominator "; r.set(18,0); cout << "r is "; r.printquotient(cout); } //end testSetandEuclid void testAlternateConstructor() { Rational p(85,50); cout << "\nAlternate constructor, common factor: "; p.printquotient(cout); Rational p0(77,0); cout << "\nAlternate constructor, 0 denominator: "; p0.printquotient(cout); }//end testAlternateConstructor void testProdAndDivide() { Rational a(4,6),b(5,-2),c(0,3); cout << "\nproducts and quotients\n"; (a*b).printquotient(cout); cout << '\t'; (a/b).printquotient(cout); cout << '\t'; (c/b).printquotient(cout); cout << '\t'; (b/c).printquotient(cout); } void testCompares() { Rational a(5,3), b(-4,6), c(2,-3), d(-4,2); cout << "\nComparisons\n"; if (a>b) cout << "a greater than b"; if (b==c) cout << "\nb and c are equal\n"; if (5 == a) cout << "a is an integer = 5\n"; else cout << " a is not an integer = 5\n"; if (-2 == d) cout << "d is and integer =-2\n"; if(d == -2) cout << "-2 = d\n"; if (a==c) cout << "\nTrouble.\n"; } void testInputOutput() { Rational r(2,3); Rational p; cout << "\nOutput\n"; r.printdecimal(cout) << " is decimal and "; r.printquotient(cout) << " is a quotient.\n"; cout << "Enter rational number r and p in the form #/# "; p.read(r.read(cin)); cout << "\np is "; p.printquotient(cout); cout << "\tand r is "; r.printquotient(cout); } void testAddAndSubtract() { Rational r(2,3), p(5,-2); cout << "\nSum and Difference\n"; (r+p).printquotient(cout); cout << '\t' ; (r-p).printquotient(cout); cout << '\t'; r=r-p; r.printquotient(cout); } int main() { //setting up input and output files ofstream testout("rationalout.txt"); ifstream testin("rationalin.txt"); //testing the default constructor Rational r,q; cout << "r is "; r.printquotient(cout); testout << "q is "; q.printquotient(testout); //test set and Euclid testSetAndEuclid(r); //test alternate constructor testAlternateConstructor(); //test operations testProdAndDivide(); testCompares(); testAddAndSubtract(); testInputOutput(); return 0; } #endif