/******************************************************* FILE NAME = rational.cpp (problem 2) PROGRAMMER NAME - Justin C. Miller DATE - 09/17/2003 BUGS - I believe that everything works properly DESCRIPTION - This program defines the functions in rational.h This is for Problem 1 *******************************************************/ #ifndef rational_cpp #define rational_cpp #include #include #include #include "bigint.h" #include "rational.h" using namespace std; BigInt rational::ceiling(void) const { BigInt zero(0) ; BigInt one(1) ; if(this->numerator() == zero) return zero ; // if zero else if(this->numerator() > zero){ BigInt result = this->numerator() / this->denominator() ; if( this->numerator() % this->denominator() != zero) result = result + one ; return result; }else{ return BigInt(this->numerator() / this->denominator()) ; }//else }//end of ceiling BigInt rational::floor(void) const { BigInt zero(0) ; BigInt one(1) ; if(this->numerator() >= zero) return BigInt(this->numerator() / this->denominator()) ; else{ BigInt result = this->numerator() / this->denominator() ; BigInt negOne(-1) ; BigInt test = (negOne*this->numerator()) % this->denominator() ; if(test != zero) result = result - one ; return result ; }//else }//end of ceiling rational operator+(const rational & left, const rational & right){ rational r(left.numerator()*right.denominator() + left.denominator()*right.numerator(), left.denominator() * right.denominator()) ; // the constructor normalizes for me return r; }//end of operator+ rational operator-(const rational & left, const rational & right){ rational r(left.numerator()*right.denominator() - left.denominator()*right.numerator(), left.denominator() * right.denominator()) ; // the constructor normalizes for me return r; }//end of operator- rational operator*(const rational & left, const rational & right){ rational r(left.numerator()*right.numerator(), left.denominator() * right.denominator()) ; // the constructor normalizes for me return r; }//end of operator* rational operator/(const rational & left, const rational & right){ rational r(left.numerator()*right.denominator(), left.denominator() * right.numerator()) ; // the constructor normalizes for me return r; }//end of operator/ ostream & operator<<(ostream & out, const rational & r){ out << r.numerator() << "/" << r.denominator() ; return out ; }//end of operator<< istream & operator>>(istream & in, rational & r){ char slash ; // because i'm a friend i have access to r's top and bottom in >> r.top >> slash >> r.bottom ; r.normalize() ; return in ; }//end of operator>> BigInt gcd(BigInt x, BigInt y) { BigInt a(y); while (a != BigInt(0)) { y = a; a = x % a; x = y; } return x; } rational::rational() { top=BigInt(0); bottom=BigInt(1); } rational::rational(int i) { top=BigInt(i); bottom=BigInt(1); } rational::rational(int i, int j) { assert(j!=BigInt(0)); top=BigInt(i); bottom=BigInt(j); normalize(); } rational::rational(const rational &source) { top=source.top; bottom=source.bottom; } rational::rational(BigInt i) { top=i; bottom=BigInt(1); } rational::rational(BigInt i, BigInt j) { assert(j!=BigInt(0)); top=i; bottom=j; normalize(); } BigInt rational::numerator() const{ return top; } BigInt rational::denominator() const{ return bottom; } void rational::operator = (const rational &r) { top = r.top; bottom = r.bottom; } void rational::operator += (const rational &r) { top = top * r.bottom + r.top * bottom; bottom = r.bottom * bottom; (*this).normalize(); } void rational::operator -= (const rational &r) { top = top * r.bottom - r.top * bottom; bottom = r.bottom * bottom; (*this).normalize(); } void rational::operator *= (const rational &r) { top = top * r.top; bottom = bottom * r.bottom; (*this).normalize(); } void rational::operator /= (const rational &r) { top = top * r.bottom; bottom = bottom * r.top; (*this).normalize(); } // returns 1 if p > q, returns 0 if p = q, and -1 if p < q int rational::compare(const rational &r) const { if (top * r.bottom > bottom * r.top) return 1; if (top * r.bottom < bottom * r.top) return -1; return 0; } void rational::normalize() { bool flag = false ; if(top < BigInt(0)){ flag = true ; top = top * BigInt(-1) ; } BigInt m = gcd(top, bottom); assert(m != BigInt(0)); top /= m; bottom /= m; if(flag) top = top * BigInt(-1) ; } #endif