# Rational class

Printable View

• 03-10-2006
Kayoss
Rational class
Here is the start of my rational class program. The idea is to add, subtract, multiply and divide two fractions. You can see I've declared 1/3 as the first fraction and 2/5 as the second. However I'm not sure how to point to the 1 separate of the 3, and the 2 separate of the 5, to perform the addition correctly. Do I have to set up numerator1 and numerator2, etc?

Also, I have a simplify function to reduce the fraction. Currently the first fraction will reduce (for example, if I replaces 1/3 with 4/8 it would return 1/2) but the second will not, and I'm not sure why.

Code:

```#include <iostream> using namespace std; class Rational {   public:       Rational(int n=0,int d=1)       {         numerator = n;         denominator = d;       }       void print()       {         cout << numerator << "/" << denominator << endl;       }       void operator = (Rational c)       {         numerator = c.numerator;         denominator = c.denominator;       }       void Rational::simplify() // to simplify the fraction           {         int n=(int)this->numerator;         int d=(int)this->denominator;         int i=2;         while((i<=n) && (n!=1))       {           while((n/i==(int)n/i) && (d/i ==(int)d/i))           {               n/=i;               d/=i;           }                 i++;       }           numerator=n;           denominator=(n==0)?1:d;           }       Rational operator + (Rational c) // adds fractions       {         Rational::simplify();         Rational t;         t.numerator = numerator + c.numerator;         t.denominator = denominator + c.denominator;         return t;       }       Rational operator - (Rational c) // subtracts fractions       {         Rational::simplify();         Rational t;         t.numerator = numerator - c.numerator;         t.denominator = denominator - c.denominator;         return t;       }         Rational operator * (Rational c) // multiplies fractions         {             Rational::simplify();             Rational t;             t.numerator = numerator * c.numerator;             t.denominator = denominator * c.denominator;             return t;         }         Rational operator / (Rational c) // divides fractions         {             Rational::simplify();             Rational t;             t.numerator = numerator / c.numerator;             t.denominator = denominator / c.denominator;             return t;         }             private:       int numerator;       int denominator; }; // end class Rational int main() {   Rational a(1,3),b(2,5); // a is (1/3); b is (2/5) // a reduces, b does not   Rational z; // test variable to check default constructor   Rational c; // instantiates variable c to class Rational initializing to zero   c = a + b; // currently adds two numerators (1 + 2) and two denominators (3 + 5)   Rational d; // instantiates d   d = a - b; // subtracts a from b   Rational e; //   e = a*b;   Rational f;   f = a/b;   cout << "First fraction is: " << endl;   a.print();   cout << "\nSecond fraction is: " << endl;   b.print();   cout << "\nAdding first fraction to second fraction: " << endl;   c.print();   cout << "\nSubracting first fraction from second fraction: " << endl;   d.print();   cout << "\nMultiplying first fraction to second fraction: " << endl;   e.print();   cout << "\nDividing first fraction by second fraction: " << endl;   f.print();   cout << "\nTest default fraction: " << endl;   z.print(); return 0; }```
• 03-10-2006
OnionKnight
Shouldn't the constructor call Rational::simplify() after assigning the variables?
• 03-10-2006
Decrypt
Quote:

However I'm not sure how to point to the 1 separate of the 3, and the 2 separate of the 5
You've made the numerator and denominator private, which is good, so to allow access to them w/in a program, you'll need to implement accessor functions:

Code:

```int Rational::get_numerator() {   return numerator; }```
Use a similar function for the denominator. This allows anyone using your Rational class in their program to reference the private data members of your class, without allowing direct access (making them public). So in your program, if you want to display the numerator of a, you just:

Code:

`cout << a.get_numerator();`
• 03-10-2006
Daved
You refer to simplify as Rational::simplify(), but there is no need for the Rational:: part when you define it inline or call it from the function.

You don't need the copy assignment operator, it is just doing the default copy.

Your addition isn't correct mathematically. 1/2 + 2/3 does not equal 3/5. Same for your subtraction. You can have local variables within the addition function to save the non-reduced values when you make the denominators match. If you want you can call them numerator1 and numerator2 and denominator (since the denominator must be the same to add them).

Your division won't work very well because of problems with integer division. Perhaps you should just flip the second operand and multiply.

>> a is (1/3); b is (2/5) // a reduces, b does not
a does not reduce.

Normally, you want operator+ to be a non-member function that makes a temporary copy of the first operand and then uses += to add the second operand to it, returning the copy. Same for operator-, operator* and operator/. This would mean that you would implement the operations in operator+=, operator-=, operator*= and operator/=.
• 03-10-2006
CornedBee
In addition, you should make every member function that does not modify the object const, so that you can call them on const instances.

Also, your simplify function is broken, again due to integer division. (The gist of it is that (n/i==(int)n/i) is always true if n and i are integers.) If it weren't for integer division, it would still be broken due to precision problems, but the bug would be more subtle.