home *** CD-ROM | disk | FTP | other *** search
- // \EXAMPLES\EX1301.CPP
-
- // cout and cin from iostream
- #include <iostream.h>
- // MAX_INT used to prevent integer overflow in fraction
- #include <limits.h>
-
- // this global function is called by member function reduce()
- int gcd(int n,int d);
-
- //
- // Fraction base class
- //
- class fraction {
- protected: // the derived classes need access to these
- int num; // num includes the sign of fraction
- int denom; // denominator always positive
- virtual void reduce ()=0; // put Fractions in simplest form
- public:
- fraction (int i=0, int j=1): num(i), denom(j) { };
- fraction (double);
- ~fraction() {};
- friend istream& operator>>(istream& i, fraction& f);
- };
-
- //
- // pfraction class
- // derived from fraction
- //
-
- class pfraction : public fraction {
- public:
- // constructors
- pfraction (int i=0, int j=1): fraction(i,j) { reduce(); };
- pfraction (double x);
- // conversion functions
- operator double();
- operator int();
- void reduce();
- // prefix increment and decrement
- pfraction operator++ ()
- { return pfraction ( num + denom, denom); };
- pfraction operator-- ()
- { return pfraction ( num - denom, denom); };
- // postfix increment and decrement
- pfraction operator++ (int)
- { return pfraction( num + denom, denom); };
- pfraction operator-- (int)
- { return pfraction( num - denom, denom); };
- // overloading > == and <
- friend
- int operator>(const pfraction& f1, const pfraction& f2);
- friend
- int operator==(const pfraction& f1, const pfraction& f2);
- friend
- int operator<(const pfraction& f1, const pfraction& f2);
- // overloading unary math operators + - ++ -- ...
- pfraction operator+ ();
- pfraction operator- ();
- // overloading binary math operators + - * / ...
- friend
- pfraction operator+(const pfraction& f1, const pfraction& f2);
- friend
- pfraction operator-(const pfraction& f1, const pfraction& f2);
- friend
- pfraction operator*(const pfraction& f1, const pfraction& f2);
- friend
- pfraction operator/(const pfraction& f1, const pfraction& f2);
- // output operator
- friend
- ostream& operator<<(ostream& , const pfraction&);
- };
-
- //
- // mfraction class
- // derived from fraction
- //
- //
- // In this class, the whole part of the fraction is stored
- // separately from the fractional part. If the value can be
- // expressed as a proper fraction, the whole part equals zero.
- //
-
- class mfraction : public fraction {
- private:
- int whole;
- public:
- // constructors
- mfraction (int i=0, int j=0, int k = 1) :
- whole(i), fraction(j,k)
- { reduce(); }
- mfraction (double x);
- // conversion functions
- operator double();
- operator int();
- void make_pure();
- void reduce();
- // prefix forms
- mfraction operator++ ()
- { return mfraction ( whole++, num, denom); };
- mfraction operator-- ()
- { return mfraction ( whole--, num, denom); };
- // postfix forms
- mfraction operator++ (int)
- { return mfraction( whole++, num, denom); };
- mfraction operator-- (int)
- { return mfraction( whole--, num, denom); };
- // overloading > == and <
- friend
- int operator> (const mfraction& f1, const mfraction& f2);
- friend
- int operator== (const mfraction& f1, const mfraction& f2);
- friend
- int operator< (const mfraction& f1, const mfraction& f2);
- // overloading unary math operators + - ++ -- ...
- mfraction operator+ ();
- mfraction operator- ();
- // overloading binary math operators + - * / ...
- friend mfraction
- operator+ (const mfraction& f1, const mfraction& f2);
- friend mfraction
- operator- (const mfraction& f1, const mfraction& f2);
- friend mfraction
- operator* (const mfraction& f1, const mfraction& f2);
- friend mfraction
- operator/ (const mfraction& f1, const mfraction& f2);
- // output operator
- friend ostream& operator<<(ostream& , const mfraction&);
- };
-
- //
- // Conversion functions for pfraction and mfraction
- //
-
- double pfraction::operator double(pfraction f) {
- return double(num)/double(denom);
- }
-
- double mfraction::operator double(mfraction f) {
- return whole + (double(num)/double(denom));
- }
-
- int pfraction::operator int(int i) {
- return int(double(num)/double(denom));
- }
-
- int mfraction::operator int(int i) {
- return whole + int(double(num)/double(denom));
- }
-
- //
- // input and output operators for pfraction and mfraction
- //
-
- ostream& operator<<(ostream& o, const pfraction& f) {
- o << f.num << "/" << f.denom;
- return o;
- }
-
- ostream& operator<<(ostream& o, const mfraction& f) {
- o << f.whole << " " << f.num << "/" << f.denom;
- return o;
- }
-
- istream& operator>>(istream& i, fraction& f) {
- char c;
- i >> f.num >> c >> f.denom;
- f.reduce();
- return i;
- }
-
- //
- // Definitions:
- // arithmetic operators for pfraction and mfraction.
-
- pfraction operator+ (const pfraction& f1, const pfraction& f2 ) {
- int n = f1.num*f2.denom + f2.num*f1.denom;
- int d = f1.denom * f2.denom;
- return pfraction(n,d);
- }
-
- mfraction operator+ (const mfraction& f1, const mfraction& f2 ) {
- int n = f1.num*f2.denom + f2.num*f1.denom;
- int d = f1.denom * f2.denom;
- int w = f1.whole + f2.whole;
- if ( w*n < 0 ) { // do signs of whole and fraction agree
- if ( n < 0 ) { // if fraction negative, subtract one from
- n = n + d; // whole and add to fraction
- w--;
- }
- else {
- n = n - d; // if fraction positive, subtract one from
- w++; // fraction and add to whole
- }
- }
- return mfraction(w,n,d);
- }
-
- pfraction operator- ( const pfraction& f1, const pfraction& f2 )
- {
- int n = f1.num*f2.denom - f2.num*f1.denom;
- int d = f1.denom * f2.denom;
- return pfraction(n,d);
- }
-
- mfraction operator- ( const mfraction& f1, const mfraction& f2 )
- {
- int n = f1.num*f2.denom - f2.num*f1.denom;
- int d = f1.denom * f2.denom;
- int w = f1.whole - f2.whole;
- if ( w*n < 0 ) { // do signs of whole and fraction agree
- if ( n < 0 ) { // if fraction negative, subtract one from
- n = n + d; // whole and add to fraction
- w--;
- }
- else {
- n = n - d; // if fraction positive, subtract one from
- w++; // fraction and add to whole
- }
- }
- return mfraction(w,n,d);
- }
-
- pfraction operator* ( const pfraction& f1, const pfraction& f2 )
- {
- int n = f1.num * f2.num;
- int d = f1.denom * f2.denom;
- return pfraction(n,d);
- }
-
- mfraction operator* ( const mfraction& f1, const mfraction& f2 )
- {
- int n = f1.num * f2.num;
- int d = f1.denom * f2.denom;
- int n2 = f1.num * f2.whole * f2.denom;
- int n3 = f2.num * f1.whole * f1.denom;
- int w = f1.whole * f2.whole;
- if ( w*n < 0 ) { // do signs of whole and fraction agree
- if ( n < 0 ) { // if fraction negative, subtract one from
- n = n + d; // whole and add to fraction
- w--;
- }
- else {
- n = n - d; // if fraction positive, subtract one from
- w++; // fraction and add to whole
- }
- }
- return mfraction(w,n + n2 + n3,d);
- }
-
- pfraction operator/( const pfraction& f1, const pfraction& f2 )
- {
- int n = f1.num * f2.denom;
- int d = f1.denom * f2.num;
- return pfraction(n,d);
- }
-
- mfraction operator/( const mfraction& f1, const mfraction& f2 )
- {
- mfraction ft1 = f1;
- mfraction ft2 = f2;
- ft1.make_pure(); // convert to pure fractions
- ft2.make_pure();
- int n = ft1.num * ft2.denom;
- int d = ft1.denom * ft2.num;
- return mfraction(0,n,d);
- }
-
- //
- // Functions used in implementation of fraction
- //
-
- fraction::fraction(double x) : num(0), denom(1)
- {
- double y = x < 0 ? -x : x; // avoid negative numbers
- int n = int(y); // numerator = whole part
- int d = 1; // denominator
- y -= n; // y is fractional
- int acc = INT_MAX >> 1 ; // accuracy is limited
- while ( n < acc && d < acc ) { // stop before overflow
- n <<= 1; d <<=1; // parse bit by bit
- y += y; // next bit of accuracy
- if (y >= 1.0) { n +=1; y -=1; }//
- if ( y < 1e-10 ) break; // stop when residue tiny
- };
- if ( x < 0 ) n = -n; // reinstate sign if < 0
- num = n; denom = d; reduce(); // create the fraction
- }
-
- //
- // reduce for pfraction
- //
- // This function reduces a pfraction object to its simplest form.
- //
-
-
- void pfraction::reduce()
- {
- // what to do when demon = 0? for simplicity set fraction=0/1
- if ( denom == 0 ) { num = 0; denom = 1; }
- // check sign - should be on num only
- if ( denom < 0 ) { num = - num; denom = - denom; };
- // reduce to simplest form
- // - divide num and demon by greatest common factor
- int g = gcd(num, denom);
- if (g > 1) { num = num/g; denom = denom/g;};
- };
-
- //
- // reduce for mfraction
- //
- // Reduces mfraction object to simplest form. Ensures that sign
- // of whole part and fractional part agree. Ensures that
- // fractional part is a proper fraction.
- //
-
- void mfraction::reduce()
- {
- // what to do when demon = 0? for simplicity set fraction=0/1
- if ( denom == 0 ) { num = 0; denom = 1; }
- // check sign - should be on num only
- if ( denom < 0 ) { num = - num; denom = - denom; };
- // reduce to simplest form
- // - divide num and demon by greatest common factor
- int g = gcd(num, denom);
- if (g > 1) { num = num/g; denom = denom/g;}
- // express as a mixed fraction
- whole = whole + int(num/denom);
- num = num%denom;
- // ensure sign is on whole part unless whole part is zero
- if ( num < 0 && whole != 0 ) {
- if ( whole < 0 ) {
- num = - num;
- }
- else {
- num = num + denom;
- whole--;
- }
- }
- }
-
- //
- // make_pure for mfraction
- //
- // Convert the mixed fraction into a mixed fraction
- // where the whole part is equal to zero.
- //
-
- void mfraction::make_pure() {
- num = num + (denom * whole);
- whole = 0;
- }
-
- //
- // gcd function
- //
- // Takes two integer arguments. Returns the
- // greatest common divisor of these two values.
- //
-
- int gcd(int nn, int dd) // Euclid's algorithm for gcd
- { int n = nn < 0 ? -nn : nn;
- int d = dd < 0 ? -dd : dd;
- return n % d == 0 ? d : gcd( d, n % d);
- };
-
- //
- // main() function
- //
- // Creates two mfraction objects and performs
- // arithmetic operations on them.
- //
-
- void main() {
- mfraction mf1, mf2;
- cout << " Enter two fractions " << endl;
- cin >> mf1 >> mf2;
- cout << " Here is mf1 " << mf1 << endl;
- cout << " Here is mf2 " << mf2 << endl;
- cout << " Sum is: " << mf1 + mf2 << endl;
- cout << " Difference is: " << mf1 - mf2 << endl;
- cout << " Product is: " << mf1 * mf2 << endl;
- cout << " Quotient is: " << mf1 / mf2 << endl;
- }
-
-