Beginner here wondering where to start with this assignment.

Wondering where to start on this C++ homework assignment involving friend functions and overloading operators implemented in a Rational class. These are the instructions:

Your class will need to store two internal, integer values for each Rational number, the numerator (top) and denominator (bottom) of the fraction. It will have three constructor functions, with zero, one and two arguments, used as follows:

Rational test1, test2(10), test3(1, 2);

The declaration for test1 calls the default (no argument) constructor, which should set the value to 0. (Like any other whole number, zero will have a 1 in the denominator: we cannot divide by zero.) The declaration for test2 calls a constructor with one argument. The value for test2 will be 10, stored as 10 on the top and 1 on the bottom. The declaration for test3 calls the constructor with two arguments. test3 is equal to 0.5, with 1 on the top and 2 on the bottom.

All of the operators required in the problem should be provided for the Rational class as overloaded, Friend functions. In general, you should be able to execute code such as following:

// Display the three values to test cout
cout << "\nTest1 equals " << test1;
cout << "\nTest2 equals " << test2;
cout << "\nTest3 equals " << test3;
// Test our operators
cout << "\nTest1 * Test2 equals " << test1*test2;
cout << "\nTest1 / Test3 equals " << test1/test3;
cout << "\nTest2 + Test3 equals " << test2+test3;
cout << "\nTest3 - Test1 equals " << test3-test1;
if (test1 == test2)
cout << "\nTest1 is equal to Test2";
if (test1 < test2)
cout << "\nTest1 is less than Test2";

and so on until you test all the implemented member functions and Friend functions of the Rational class.

This is what I have so far


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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
 
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <time.h>

class Rational
{
    private:
        int numerator;
        int denominator;
        void reduce();

    public:
        Rational();
        Rational(int n, int d);
        int getNumerator();
        int getDenominator();
        void add(Rational addend);
        void sub(Rational subtractor);
        void mul(Rational multiplicand);
        void div(Rational dividend);
        int greatestCommonDenominator(int a,int b);
        bool less(Rational comparator);
        bool eq(Rational comparator);
        bool neq(Rational comparator);
        void output(std::ostream& oss);
};

Rational::Rational() {
   numerator = 0;
   denominator = 1;
}

Rational::Rational(int n, int d) {
//   cout<<"Creating rational number "<<n<<"/"<<d<<endl;
   numerator = n;
   denominator = d;

   if (numerator < 0 and denominator < 0) {
       numerator = -numerator;
       denominator = - denominator;
   }
   if (numerator*denominator < 0) {
       cout<<"Error negative fraction"<<std::endl;
       exit(1);
   }
}
int Rational::getNumerator() {
   return numerator;
}
int Rational::getDenominator() {
   return denominator;
}
int Rational::greatestCommonDenominator(int a, int b) {
   //cout<<"Finding greatest common denominator of "<<a<<" and "<<b<<endl;
   int gcd = 1;
   int smallerNum = a;
   if ( a > b ) {
       smallerNum = b;
   }
   for ( int i = 1; i <= smallerNum; i++ ) {
       if (((a % i) == 0) and ((b % i) == 0)) {
           gcd = i;
       }
   }
   //cout<<"Greatest common denominator is "<<gcd<<endl;
   return gcd;
}
void Rational::reduce() {
   int gcd = greatestCommonDenominator(numerator, denominator);
   numerator = numerator / gcd;
   denominator = denominator / gcd;
}

void Rational::add(const Rational addend) {
   numerator = numerator*addend.denominator + addend.numerator*denominator;
   denominator = denominator*addend.denominator;
   reduce();
   return;
}
void Rational::sub(Rational subtractor) {
   numerator = numerator*subtractor.denominator - subtractor.numerator*denominator;
   denominator = denominator*subtractor.denominator;
   if ( numerator < 0 ) {
       cout<<"Error - negative fraction"<<std::endl;
   }
   reduce();
   return;

}
void Rational::mul(Rational multiplicand) {
   numerator *= multiplicand.numerator;
   denominator *= multiplicand.denominator;
   reduce();
}

void Rational::div(Rational dividend) {
   denominator *= dividend.numerator;
   numerator *= dividend.denominator;
   reduce();
}

bool Rational::less(Rational comparator) {
   return (numerator*comparator.denominator < comparator.numerator*denominator);
}

bool Rational::eq(Rational comparator) {
   return (numerator*comparator.denominator == comparator.numerator*denominator);
}

bool Rational::neq(Rational comparator) {
   return !eq(comparator);
}

void Rational::output(std::ostream& oss) {
   oss<<numerator<<"/"<<denominator<<std::endl;
}

int main() {
   Rational fraction1(1,2);
   Rational fraction2(2,4);

   fraction1.add(fraction2);
   fraction1.sub(fraction2);
   if (fraction1.eq(fraction2)) {
       cout<<"Add and eq work great"<<endl;
   }
   cout<<"Just checking"<<endl;
   fraction1.output(cout);
   fraction2.output(cout);
   //insert any test code for Rational class
   return (0);
}
and your C++ question is?
Hello ethanbonneraustin,

You should start with following your instructions first.


Wondering where to start on this C++ homework assignment involving friend functions and overloading operators
implemented in a Rational class. These are the instructions:


You have no friend functions or overloaded operators yet.


It will have three constructor functions, with zero, one and two arguments, used as follows


You have covered the default, (zero argument), ctor and the ctor for the 2 arguments, but are missing the 1 for 1 argument.

In your function:
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
Rational::Rational(int n, int d)
{
    //std::cout << "Creating rational number " << n << "/" << d << '\n';
    
    numerator = n;
    denominator = d;

    if (numerator < 0 and denominator < 0)
    {
        numerator = -numerator;
        denominator = -denominator;
    }

    if (numerator*denominator < 0)
    {
        std::cout << "Error negative fraction\n";

        exit(1);  // <--- Do not use "exit()".
    }
}

int Rational::getNumerator()
{
    return numerator;
}

int Rational::getDenominator()

"exit()" is a C function. This is an unconditional exit from the program. The problem is that "exit" do not know about classes or clean them up before you leave the program. There are occasions when "exit" is useful, but I do not believe this is 1 of them.

Your include files:
1
2
3
4
#include <fstream>
#include <iostream>
//#include <stdlib.h>
//#include <time.h> 

For the last 2 you should use the C++ version "cstdlib" and "ctime", but at the moment neither are needed for the code that you have.

I am do not know what you have learned, but when it comes to the {}s pick a style and be consistent in its use.

See: https://en.wikipedia.org/wiki/Indentation_style#Brace_placement_in_compound_statements I find the "Allman" style to be the easiest to read. Unless you want to make a change stick with what you have learned.

In the code presented notice the use of blank lines to break up the code. This makes it much easier to read and follow and that should be 1 of the first goals. You are not writing the code for the compiler, but for someone to read, so make it easy to read.

Andy
Topic archived. No new replies allowed.