How to write a struct that shows a fraction?

Here is my prompt:
********************************************************************************
Create a program that uses a struct to model a single fraction.

Then create functions to add, subtract, multiply and divide two fractions WITHOUT CONVERTING THEM TO DECIMALS!

Use the rules of mathematics to manipulate the integers representing the top and bottom of the fractions.

Do not, at any time, convert the fraction to decimal! Your program should prompt the user to enter the numbers representing the top and bottom of the two fractions.
********************************************************************************

I think I understand the concept of structs, but I don't understand how to make my struct model a fraction that I can perform operations on in user-defined functions.
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
  #include <cstdlib>
#include <iostream>

using namespace std;

struct Fraction
{
    int numerator;
    int denominator;
};
int addition(int num1, int den1, int num2, int den2)
{
    int n1, d1, n2, d2, result;
    result = ((n1)/(d1)) +((n2) + (d2));
    return result;
}     

int main(int argc, char *argv[])
{
    int sum, difference, product, quotient;
    Fraction sFract1;
    sFract1.numerator;
    sFract1.denominator;
    Fraction sFract2;
    sFract2.numerator;
    sFract2.denominator;
    cout << "Enter the numerator of the first fraction: ";
    cin >> sFract1.numerator;
    cout << "Enter the denominator of the first fraction: ";
    cin >> sFract1.denominator;
    cout << "Enter the numerator of the second fraction: ";
    cin >> sFract2.numerator;
    cout << "Enter the denominator of the second fraction: ";
    cin >> sFract2.denominator;
    cout << "Fraction 1 = " << sFract1.numerator << "/" << sFract1.denominator << endl;
    cout << "Fraction 2 = " << sFract2.numerator << "/" << sFract2.denominator << endl;
    sum = addition(sFract1.numerator, sFract1.denominator, sFract2.numerator, sFract1.denominator);
    cout << "Fraction 1 = " << sFract1.numerator << "/" << sFract1.denominator << " + " << sFract2.numerator << "/" << sFract2.denominator << " = " << sum << endl;
    
    system("PAUSE");
    return EXIT_SUCCESS;
}


It compiles and runs, however, when I try to use the addition function the program crashes. I think I know why it crashes; in the addition function I tell two numbers to divide, which would create a double variable, but I have it set as an int variable. Also, I know that my statements showing what my fractions are are more complicated than they need to be. How can I fix all of this?
Your addition() divides uninitialized local variable n1 with uninitialized local variable d1. The result is undefined.

Imagine, that you could add two Fractions like this:
Fraction f3 = f1 + f2;
What do you need for it? An operator+ function that takes two Fractions and returns a Fraction. You can define such function.

What do you need for addition? You can add two fractions by adding their numerators, if they have same denominator. How do you get that? You multiply. n3=n1*d2+n2*d1

Compute greatest common divisor of the numerator and denumerator of a fraction. By definition, you can divide by that number and still get integers.


Frankly, I thought that this is elementary mathematics.
the program crashes because you didn't initialize your variables in the addition function

Question: what are lines 22, 23, 25, and 26 supposed to do?

I would pass the struct to your addition function not the data members
Last edited on
I thought that I was declaring variables for the struct in lines 22, 23, 25, and 26. How do I pass the struct to my function and how can I make it display a fraction as a complete fraction, not just one integer as the program is doing now.
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
#include <cstdlib>
#include <iostream>

using namespace std;

struct Fraction
{
    int numerator;
    int denominator;
};
int addition(int num1, int den1, int num2, int den2)
{
    int result;
    result = ((num1)/(den1)) +((num2) + (den2));
    return result;
}     

int main(int argc, char *argv[])
{
    int sum, difference, product, quotient;
    Fraction sFract1;
    sFract1.numerator;
    sFract1.denominator;
    Fraction sFract2;
    sFract2.numerator;
    sFract2.denominator;
    cout << "Enter the numerator of the first fraction: ";
    cin >> sFract1.numerator;
    cout << "Enter the denominator of the first fraction: ";
    cin >> sFract1.denominator;
    cout << "Enter the numerator of the second fraction: ";
    cin >> sFract2.numerator;
    cout << "Enter the denominator of the second fraction: ";
    cin >> sFract2.denominator;
    cout << "Fraction 1 = " << sFract1.numerator << "/" << sFract1.denominator << endl;
    cout << "Fraction 2 = " << sFract2.numerator << "/" << sFract2.denominator << endl;
    sum = addition(sFract1.numerator, sFract1.denominator, sFract2.numerator, sFract1.denominator);
    cout << "Fraction 1 = " << sFract1.numerator << "/" << sFract1.denominator << " + " << sFract2.numerator << "/" << sFract2.denominator << " = " << sum << endl;
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
How do I pass the struct to my function

How do you pass std::string or integer to a function? Why would type Fraction be any different?


Your addition. Lets calculate 1/3 + 2/3. Your functions says that the result is 1/3 + 2 + 3, which equals 5 and 1/3. (a+b) should equal (b+a), but 2/3 + 1 + 3 is only 4 and 2/3. Furthermore, back in school 1/3+2/3 was only 1. Who is correct?

"But denumerator is not always same." Sure, for example 1/2 + 2/3
== (3*1)/(3*2) + (2*2)/(2*3) == 7/6


Your lines 35,36, and 38 print out sFract1 and sFract2. Wrap the essential bits to a function. See http://www.cplusplus.com/reference/string/string/operator%3C%3C/ for an example of function signature.
Last edited on
Basically it needs to look somethign like this:

Also you probably want to simplify the fractions based on their least common denominator (lcd)
If you don't understand let us know.

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
#include <iostream>

struct Fraction
{
        Fraction( int numerator , int denominator = 1 );
        Fraction operator+( Fraction rhs );
        friend std::ostream &operator<<( std::ostream &stm , const Fraction &rhs );
    private:
        int numerator , denominator;
};

Fraction::Fraction( int numerator , int denominator )
: numerator( numerator ) , denominator( denominator ){}

Fraction Fraction::operator+( Fraction rhs )
{
    Fraction result = *this;
    rhs.numerator *= result.denominator;
    result.numerator *= rhs.denominator;
    result.denominator *= rhs.denominator;
    
    result.numerator += rhs.numerator;
    
    return( result );
}

std::ostream &operator<<( std::ostream &stm , const Fraction &rhs )
{
    if( rhs.denominator == 1 ) return( stm << rhs.numerator );
    return( stm << rhs.numerator << '/' << rhs.denominator );
}

int main()
{
    Fraction f1( 4 , 27 ) , f2( 4 );
    std::cout << f1 <<  " + " << f2 << " = " << ( f1 + f2 ) << std::endl;
}
What are you doing in lines 12, 13, 15, and 27? I'm at extremely basic entry level programming and some of the terms such as "friend", "const", and "private" make no sense to me at all. Also, I meant to put this
1
2
3
4
5
6
int addition(int num1, int den1, int num2, int den2)
{
    int result;
    result = ((num1)/(den1)) +((num2)/(den2));
    return result;
}

as my addition function. If you could explain what's going on in the aforementioned lines I'm sure it would help a lot.
Line 12 and 13 I am defining the constructor. Line 13 is initializing the private variables in the class when the constructor is created.
It is [b]almost[b] identical to
1
2
3
4
5
6
7
Fraction::Fraction( int numerator, int denominator )
{
    this->numerator = numerator;
    this->denominator = denominator;
    //this is pointing to the private variables. if you dont want to use rename the param
   //and do numerator = new_param;
}


Except my version initializes using an initialization list and the second example just assigns values to them. The initializer list is the c++11 version.

Line 15 I am overloading the '+' operator so you can do object1 + object 2 ( line 36 in my code )

You can overload most of the operators a few examples: + , - , * , / , % , << , >> , =

Line 27 is another overload but this time I am overloading operator << for the output stream so you can output the object using cout ( line 36 ).

Friend is a keyword in classes that lets a function outside of the class access all of its private variables.

Const is a keyword that tells the compiler that a variable is read-only or can not be modified.

Private is a keyword in a class that tells the compiler that only the class object may access them. Other objects / derived classes may not access them.

Check out chapter 8 and 9 here:
http://www.learncpp.com/

And check out these:
http://www.cplusplus.com/doc/tutorial/classes/
http://www.cplusplus.com/doc/tutorial/classes2/
http://www.cplusplus.com/doc/tutorial/inheritance/

Also technically when you do addition you wouldn't want your function to look like that.

Because you call the function using one object so it would be like Obj.add( obj2 )

Also you are adding two fractions then returning an int???
You should return a string or Fraction object ( string so you can output easy I suppose ) You're trying to return a double anyways.
Then you could do something like this

1
2
3
4
5
6

Fraction Fraction::Add( Fraction obj2 )
{
    obj2.numerator *= denominator;
    obj2.numerator += numerator * obj2.denominator;
    return( obj2 );


Or this

1
2
3
4
5
6
7
8
9
std::string Fraction::Add( Fraction obj2 )
{
    obj2.numerator *= denominator;
    obj2.numerator += numerator * obj2.denominator;
    obj2.denominator *= denominator;
    std::stringstream ss;
    ss << obj2.numerator << '/' << obj2.denominator;
    return( ss.str() );
}


http://ideone.com/cLOjjH

I was able to ask my instructor and completed my program without using anything unfamiliar to me.
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
#include <cstdlib>
#include <iostream>

using namespace std;

struct Fraction
{
    int numerator;
    int denominator;
};
void PrintFraction(Fraction sFraction)
{
     cout << sFraction.numerator << "/" << sFraction.denominator;
}
Fraction addition(Fraction fract1, Fraction fract2)
{
    Fraction result;
    result.numerator = (fract1.numerator * fract2.denominator) + (fract2.numerator * fract1.denominator);
    result.denominator = fract1.denominator * fract2.denominator;
    return result;
}
Fraction subtraction(Fraction fract1, Fraction fract2)
{
     Fraction result;
     result.numerator = (fract1.numerator * fract2.denominator) - (fract2.numerator * fract1.denominator);
     result.denominator = fract1.denominator * fract2. denominator;
     return result;     
}   
Fraction multiplication(Fraction fract1, Fraction fract2)
{
     Fraction result;
     result.numerator = fract1.numerator * fract2.numerator;
     result.denominator = fract1.denominator * fract2. denominator;
     return result;
}
Fraction division(Fraction fract1, Fraction fract2)
{
     Fraction result;
     result.numerator = fract1.numerator * fract2.denominator;
     result.denominator = fract1.denominator * fract2.numerator;
     return result;
}

int main(int argc, char *argv[])
{
    Fraction sum, difference, product, quotient;
    Fraction sFract1;
    Fraction sFract2;
    cout << "Enter the numerator of the first fraction: ";
    cin >> sFract1.numerator;
    cout << "Enter the denominator of the first fraction: ";
    cin >> sFract1.denominator;
    cout << "Enter the numerator of the second fraction: ";
    cin >> sFract2.numerator;
    cout << "Enter the denominator of the second fraction: ";
    cin >> sFract2.denominator;
    cout << endl;
    cout << "Fraction 1 = ";
    PrintFraction(sFract1);
    cout << endl;
    cout << "Fraction 2 = ";
    PrintFraction(sFract2);
    cout << endl;
    cout << endl;
    sum = addition(sFract1, sFract2);
    PrintFraction(sFract1);
    cout << " + ";
    PrintFraction(sFract2);
    cout << " = ";
    PrintFraction(sum);
    cout << endl;
    difference = subtraction(sFract1, sFract2);
    PrintFraction(sFract1);
    cout << " - ";
    PrintFraction(sFract2);
    cout << " = ";
    PrintFraction(difference);
    cout << endl;
    product = multiplication(sFract1, sFract2);
    PrintFraction(sFract1);
    cout << " * ";
    PrintFraction(sFract2);
    cout << " = ";
    PrintFraction(product);
    cout << endl;
    quotient = division(sFract1, sFract2);
    PrintFraction(sFract1);
    cout << " / ";
    PrintFraction(sFract2);
    cout << " = ";
    PrintFraction(quotient);
    cout << endl << endl;   
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
Topic archived. No new replies allowed.