#include "rationalnumber.h" #include #include // exit using namespace std; static struct { int gcd, con, copy, des, assn, rel, add, sub, mul, div, in, out; } stats; // implicitly initialized to 0 static int gcd( int a, int b ) { for ( ;; ) { int r = a % b; if ( r == 0 ) break; a = b; b = r; } // for stats.gcd += 1; return b; } // gcd void Rationalnumber::statistics() { cerr << "gcd:" << stats.gcd << '\t' << "con:" << stats.con << '\t' << "copy:" << stats.copy << '\t' << "des:" << stats.des << '\t' << "assn:" << stats.assn << '\t' << "rel:" << stats.rel << '\t' << "add:" << stats.add << '\t' << "sub:" << stats.sub << '\t' << "mul:" << stats.mul << '\t' << "div:" << stats.div << '\t' << "in:" << stats.in << '\t' << "out:" << stats.out << endl; } // Rationalnumber::statistics bool Rationalnumber::eq( Rationalnumber &r ) { return num * r.denom == denom * r.num; } // Rationalnumber::Rationalnumber::eq bool Rationalnumber::lt( Rationalnumber &r ) { //int temp1 = denom * r.denom, temp2 = num * r.denom, temp3 = denom * r.num; //return temp1 > 0 && temp2 < temp3 || temp1 < 0 && temp2 > temp3; // if denominator is always > 0, only this check is necessary return num * r.denom < denom * r.num; } // Rationalnumber::Rationalnumber::lt void Rationalnumber::common1( int n, int d ) { num = n; denom = d; stats.con += 1; } // Rationalnumber::common1 int Rationalnumber::common2( int &n, int &d ) { if ( d == 0 ) { cerr << "Invalid rational number construction: denominator cannot be equal to 0." << endl; exit( EXIT_FAILURE ); } // exit if ( d < 0 ) { d = -d; n = -n; } // move sign to numerator return gcd( abs( n ), d ); // simplify } // Rationalnumber::common2 Rationalnumber::Rationalnumber() { common1( 0, 1 ); } // Rationalnumber::Rationalnumber Rationalnumber::Rationalnumber( int n ) { common1( n, 1 ); } // Rationalnumber::Rationalnumber Rationalnumber::Rationalnumber( int n, int d ) { int temp = common2( n, d ); common1( n / temp, d / temp ); } // Rationalnumber::Rationalnumber Rationalnumber::Rationalnumber( const Rationalnumber &c ) { num = c.num; denom = c.denom; stats.copy += 1; } // Rationalnumber::Rationalnumber Rationalnumber::~Rationalnumber() { stats.des += 1; } // Rationalnumber::~Rationalnumber Rationalnumber &Rationalnumber::operator=( const Rationalnumber &r ) { num = r.num; denom = r.denom; stats.assn += 1; return *this; } // Rationalnumber::operator= int Rationalnumber::numerator() const { return num; } // Rationalnumber::numerator int Rationalnumber::numerator( int n ) { int prev = num; int temp = gcd( abs( n ), denom ); // simplify num = n / temp; denom = denom / temp; return prev; } // Rationalnumber::numerator int Rationalnumber::denominator() const { return denom; } // Rationalnumber::denominator int Rationalnumber::denominator( int d ) { int prev = denom; int temp = common2( num, d ); num = num / temp; denom = d / temp; return prev; } // Rationalnumber::denominator bool operator==( Rationalnumber l, Rationalnumber r ) { stats.rel += 1; return l.eq( r ); } // operator== bool operator!=( Rationalnumber l, Rationalnumber r ) { stats.rel += 1; return ! ( l.eq( r ) ); } // operator!= bool operator<( Rationalnumber l, Rationalnumber r ) { stats.rel += 1; return l.lt( r ); } // operator< bool operator<=( Rationalnumber l, Rationalnumber r ) { stats.rel += 1; return l.lt( r ) || l.eq( r ); } // operator<= bool operator>( Rationalnumber l, Rationalnumber r ) { stats.rel += 1; return ! ( l.lt( r ) || l.eq( r ) ); } // operator> bool operator>=( Rationalnumber l, Rationalnumber r ) { stats.rel += 1; return ! ( l.lt( r ) ); } // operator>= Rationalnumber Rationalnumber::operator-() { return Rationalnumber( -num, denom ); } // Rationalnumber::operator- Rationalnumber operator+( Rationalnumber l, Rationalnumber r ) { stats.add += 1; if ( l.denom == r.denom ) { // special case return Rationalnumber( l.num + r.num, l.denom ); } else { return Rationalnumber( l.num * r.denom + l.denom * r.num, l.denom * r.denom ); } // if } // operator+ Rationalnumber operator-( Rationalnumber l, Rationalnumber r ) { stats.sub += 1; if ( l.denom == r.denom ) { // special case return Rationalnumber( l.num - r.num, l.denom ); } else { return Rationalnumber( l.num * r.denom - l.denom * r.num, l.denom * r.denom ); } // if } // operator- Rationalnumber operator*( Rationalnumber l, Rationalnumber r ) { stats.mul += 1; return Rationalnumber( l.num * r.num, l.denom * r.denom ); } // operator* Rationalnumber operator/( Rationalnumber l, Rationalnumber r ) { stats.div += 1; if ( r.num < 0 ) { r.num = -r.num; r.denom = -r.denom; } return Rationalnumber( l.num * r.denom, l.denom * r.num ); } // operator/ istream &operator>>( istream &is, Rationalnumber &r ) { stats.in += 1; is >> r.num >> r.denom; int temp = Rationalnumber::common2( r.num, r.denom ); r.num /= temp; r.denom /= temp; return is; } // operator>> ostream &operator<<( ostream &os, Rationalnumber r ) { stats.out += 1; return os << r.num << "/" << r.denom; } // operator<< // Local Variables: // // compile-command: "make rationalnumber" // // End: //