Need Someone to Walk through problem with me. Please

Write a rational number class. This problem will be revisited in Chapter11, where operator overloading will make the problem much easier. For now we will use member functions add, sub, mul, div, and less that each carry out the operations +, -, *, /, and <. For example, a + b will be written a.add(b), and a < b will be written a.less(b).
Define a class for rational numbers. A rational number is a “ratio-nal” number, composed of two integers with division indicated. The division is not carried out, it is only indicated, as in 1/2, 2/3, 15/32, 65/4, 16/5. You should represent rational numbers by two int values, numerator and denominator.
A principle of abstract data type construction is that constructors must be present to create objects with any legal values. You should provide constructors to make objects out of pairs of int values; this is a constructor with two int parameters. Since every int is also a rational number, as in 2/1 or 17/1, you should provide a constructor with a single int parameter.
Provide member functions input and output that take an istream and ostream argument, respectively, and fetch or write rational numbers in the form 2/3 or 37/51 to or from the keyboard (and to or from a file).
Provide member functions add, sub, mul, and div that return a rational value. Provide a function less that returns a bool value. These functions should do the operation suggested by the name. Provide a member function neg that has no parameters and returns the negative of the calling object.
Provide a main function that thoroughly tests your class implementation. The following formulas will be useful in defining functions.
a/b + c/d = (a * d + b * c) / (b * d)
a/b - c/d = (a * d - b * c) / (b * d)
(a/b) * (c/d) = (a * c) / (b * d)
(a/b) / (c/d) = (a * d) / (c * b)
-(a/b) = (-a/b)
(a/b) < (c/d) means (a * d) < (c * b)
(a/b) == (c/d) means (a * d) == (c * b)
Let any sign be carried by the numerator; keep the denominator positive.



This is what I have so far, I know Im wrong with a lot, I just need somebody to just slowly talk me through the problem. Thanks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  #include <iostream>
using namespace std;

class Rational
{
    
public :
    
    Rational ( int initNum, unsigned int initDenom ) ;
    
    
             int getNumerator ( ) ;
    unsigned int getDenominator ( ) ;
    
    
    Rational add ( Rational secondSummand ) ;
    
    
    void output ( ostream & outputStream ) ;
    
private :
    
    int           numerator ;
    unsigned int  denominator ;
    
    int	getNumerator () const
        { return(numerator);
        
        }
    
    int	getDenominator () const
        { return(denominator);
       
        }
    
    };

Rational Rational :: add ( Rational secondSummand )
    {
    Rational result(left.getNumerator() * right.getDemoninator() +
                          left.getDemoninator() * right.getNumerator(),
                          left.getDemoninator() * right.getDemoninator()
                          );
    return result;
    }

int main()
    {
        int Rational :: getNumerator ()
        { return this -> numerator;}
        int Rational :: getDenominator ()
        { return this -> denominator;}

    
    return 0;
    
    }
Bump, please.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
using namespace std ;

/**
 * @brief
 * Instances of class %Rational represent rational numbers.
 *
 * See Programming Project 3, pages 614-615, of <em>Problem Solving with C++</em>,
 * 9th edition, by Walter Savitch.
 */

class Rational
  {

  public :
    /**
      * @brief
      * Construct an object representing a %Rational number
      *
      * @param initNum    &nbsp;&nbsp;initial numerator
      * @param initDenom  &nbsp;&nbsp;initial denominator
      */
    Rational ( int initNum, unsigned int initDenom ) ;

    /**
      * @return  the numerator of the receiver
      */
    int getNumerator ( ) ;

    /**
      * @return  the denominator of the receiver
      */
    unsigned int getDenominator ( ) ;

    /**
      * @brief
      * Add a given %Rational number to the receiver
      *
      * @param   secondSummand  &nbsp;&nbsp;the %Rational number to be
      *                          added to the receiver
      * @return  the sum of the receiver &amp; the secondSummand
      */
    Rational add ( Rational secondSummand ) ;

    /**
      * @brief
      * Write this %Rational number to a given output stream
      *
      * The %Rational number is written in the form
      * &nbsp;<em><b>&lt;numerator&gt;</b></em>&nbsp;  /
      * &nbsp;<em><b>&lt;denominator&gt;</b></em>&nbsp;;
      * for example, &nbsp;&nbsp;<code>3/4</code>&nbsp;&nbsp;
      * or &nbsp;&nbsp;<code>&minus;17/12</code>&nbsp;.\n
      * @param   outputStream  &nbsp;&nbsp;the ostream to which
      *                        the receiver is to be written
      * @return  void
      */
    void output ( ostream & outputStream ) ;

  private :
    int           numerator ;
    unsigned int  denominator ;

  } ; // end definition of Rational class

#endif // RATIONAL_H 
Here's your .h file. Take a shot at writing the implementations of the member functions declared here. Use the formulas given in your assignment to help you write the definitions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

class Rational
{
public :
    Rational(int initNum, unsigned int initDenom );
    Rational(int initNum);
    int getNumerator() const;
    unsigned int getDenominator() const;
    Rational add(const Rational& summand) const;
    Rational sub(const Rational& subtrahend) const;
    Rational mul(const Rational& multiplicand) const;
    Rational div(const Rational& divisor) const;
    bool less(const Rational& rhs) const;
    bool equals(const Rational& rhs) const;
    Rational neg() const;
    void input (std::istream& inputStream );
    void output (std::ostream& outputStream) const;

private :
    int           numerator;
    unsigned int  denominator;
};


In your .cpp file:
1
2
3
4
5
6
7
8
9
10
11
#include "Rational.h"

Rational Rational::add(const Rational& summand) const
{
    //a/b + c/d = (a * d + b * c) / (b * d)
    int newNumerator = (this->numerator * summand.getDenominator()) + (this->denominator * summand.getNumerator());
    unsigned newDenominator = this->denominator * summand.getDenominator();
    return Rational(newNumerator, newDenominator);
}

//definitions for other methods... 
Last edited on
would i basically just define these? show me one of the add, sub, mul , devide and Ill see if i can do the others.
Check the edit. :)
So this would be the sub?

1
2
3
4
5
 {int newNumerator = (this->numerator * summand.getDenominator()) +
                                          (this->denominator * summand.getNumerator());
           unsigned newDenominator = this->denominator * summand.getDenominator();
           return Rational(newNumerator, newDenominator);
          }
Last edited on
No. That's just a copy of add with the indentation all messed up.

1
2
3
4
5
6
7
8
9
//note that the parameter is named subtrahend, not summand
Rational Rational::sub(const Rational& subtrahend) const
{
    //a/b - c/d = (a * d - b * c) / (b * d)
    //the sign changes from + to - in the numerator calculation
    int newNumerator = (this->numerator * subtrahend.getDenominator()) - (this->denominator * subtrahend.getNumerator());
    unsigned newDenominator = this->denominator * subtrahend.getDenominator();
    return Rational(newNumerator, newDenominator);
}
whats the formulas for the multiplication and division and ill do them myslef?
They're all in your problem description.
The following formulas will be useful in defining functions.
What would the main function begin to look like?
How would i do the negative one? pretty sure I got the others figured out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    Rational add(const Rational& summand) const
       {
       //a/b + c/d = (a * d + b * c) / (b * d)
       int newNumerator = (this->numerator * summand.getDenominator()) +
                           (this->denominator * summand.getNumerator());
       unsigned newDenominator = this->denominator * summand.getDenominator();
       return Rational(newNumerator, newDenominator);
       }

    Rational sub(const Rational& subtrahend) const
       {
       //a/b - c/d = (a * d - b * c) / (b * d)
       int newNumerator = (this->numerator * subtrahend.getDenominator()) -
                          (this->denominator * subtrahend.getNumerator());
       unsigned newDenominator = this->denominator * subtrahend.getDenominator();
       return Rational(newNumerator, newDenominator);
       }
    
    Rational mul(const Rational& multiplicand) const
       {
       //(a/b) * (c/d) = (a * c) / (b * d)
       int newNumerator = ((this->numerator * multiplicand.getNumerator()) / 
                           (this->denominator * multiplicand.getdenominator());
       unsigned newDenominator = this->denominator * multiplicand.getDenominator();
       return Rational(newNumerator, newDenominator);
    
       }
    
    Rational div(const Rational& divisor) const;
       {
       //(a/b) / (c/d) = (a * d) / (c * b)
       int newNumerator = ((this->numerator * divisor.getDenominator()) /
                           (divisor.getNumerator * divisor.getDenominator());
       unsigned newDenominator = this->denominator * divisor.getDenominator();
       return Rational(nerNumerator, newDenominator);
    
       }
    bool less(const Rational& rhs) const
       {
       //(a/b) < (c/d) means (a * d) < (c * b)
       int newNumerator = ((this->numerator * divisor.getDenominator()) <
                           (divisor.getNumerator * divisor.getDenominator());
       unsigned newDenominator = this->denominator * divisor.getDenominator();
       return Rational(nerNumerator, newDenominator);
       }
    
    bool equals(const Rational& rhs) const
       {
       //(a/b) == (c/d) means (a * d) == (c * b)
       int newNumerator = ((this->numerator * divisor.getDenominator()) ==
                           (divisor.getNumerator * divisor.getDenominator());
       unsigned newDenominator = this->denominator * divisor.getDenominator();
       return Rational(nerNumerator, newDenominator);
       }
    
    Rational neg() const
       {
       //-(a/b) = (-a/b)
    
       {
    
bump
bump
1
2
3
4
5
6
Rational Rational::neg()
{
    //to make a negative version of the rational number, negate the numerator
    //that's what '-(a/b) = (-a/b)' is trying to say
    return Rational( -(this->numerator), this->denominator);
}


As for your other functions, mul, div, less, and equals are not implemented correctly. For mul, look at the hint you're given:
(a/b) * (c/d) = (a * c) / (b * d)

a/b is one rational number. c/d is another rational number. (a * c) / (b * d) is the resulting rational number.
a is a numerator. b is a denominator.
c is a numerator. d is a denominator.
In the result, a * c is the numerator. b * d is the denominator.
1
2
3
4
5
6
7
8
9
Rational Rational::mul(const Rational& multiplicand) const
{
    //(a/b) * (c/d) = (a * c) / (b * d)
    int newNumerator = this->numerator * multiplicand.getNumerator();  // this is the (a * c) part
    unsigned newDenominator = this->denominator * multiplicand.getDenominator(); //this is the (b * d) part

    //use them as parameters to make a new rational number and return it
    return Rational(newNumerator, newDenominator);
}


For less and equals, you aren't making a new Rational number to return. You're supposed to just return true or false based on how the parameter compares to the object calling the function.
(a/b) < (c/d) means (a * d) < (c * b)
1
2
3
4
5
6
7
8
9
10
11
12
bool Rational::less(const Rational& rhs) const
{
    //  - a/b is represented by 'this'
    //  |       - c/d is represented by the parameter rhs
    //  |       |
    //  v       v
    //(a/b) < (c/d) means (a * d) < (c * b)
    int leftHandSide = this->numerator * rhs.getDenominator();
    int rightHandSide = rhs.getNumerator() * this->denominator;

    return leftHandSide < rightHandSide;
}
I believe I fixed those. Went back over them and found my mistakes. I basically just need to know how to implement these in the main function now.
It is up to you to write out a whole bunch of other tests, but this test exercises the two constructors, the add function, the equals function, and the output function. You make objects of type 'Rational', and then you call the member functions through the objects you create.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main()
{
    Rational oneFifth(1, 5);
    Rational seven(7);

    Rational expectedSum(36, 5);
    Rational actualSum = seven.add(oneFifth);

    if (actualSum.equals(expectedSum))
    {
        std::cout << "Got what I expected.\n";
        std::cout << "What I expected: ";
        expectedSum.output(std::cout);
        std::cout << '\n';
    }
    else
    {
        std::cout << "Whoops! Something is wrong.\n";
        std::cout << "What I expected: ";
        expectedSum.output(std::cout);
        std::cout << '\n';
        std::cout << "What I calculated: ";
        actualSum.output(std::cout);
        std::cout << '\n';
    }
}
Last edited on
How would I reduce the numbers after I have the given outputs?
In your constructor, you could add extra logic to reduce the number. What you need to find is the greatest common divisor for the numerator and denominator. Once you know this number, divide both the numerator and denominator by the GCD to get the reduced version.

For example: 35 / 15
Greatest Common Divisor: 5
35 / 5 = 7
15 / 5 = 3
Reduced fraction: 7 / 3
Thanks for all your help!
Topic archived. No new replies allowed.