logic errors in fraction manipulation

Hello, I was assigned a program to write dealing with structs this week for homework. When I build the program, I don't get any syntax errors, but the program only outputs the first "3/4" line when I run it, and I get a box telling me that the "debug assertion failed". The program is supposed to find the greatest common divisor, reduce, and print any fractions that are hardcoded into it in the main function using three different functions.

Here is my code:
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
#include <iostream>
using namespace std;

class Fraction {
   Fraction();
   Fraction(int numerator, int denominator);

};

int GCD(int a, int b) {
while (a != b) {
if (b > a) {
b = b - a;
}
else {
a = a - b;
}
}

return a;
}


void reduce(int a, int b) {
int d;
while (a != b) {
if (b > a) {
d = b - a;
}
else {
d = a - d;
}
}

a = a / d;
b = b / d;

return;
}

string fractionToString(int a, int b) {

cout << a << "/" << b << endl;

return 0;
}

int main() {

fractionToString(3 , 4);
GCD(3 , 4);
reduce(3 , 4);

fractionToString(1 , 7);
GCD(1 , 7);
reduce(1 , 7);

fractionToString(2 , 8);
GCD(2 , 8);
reduce(2 , 8);

return 0;
}
Last edited on
There are two problems with your reduce() function.
1) If the condition a != b is true, the program will enter an infinite loop. Why? Because when a != b, neither a nor b is modified, so the condition a != b in while(a != b) will never be false. Thus, an infinite loop as the program has no way to exit the loop. This is what might have caused your error, though infinite loops usually just have your program run ad infinitum.
2) Also, what if a call reduce(7, 5) is made? You cannot accurately predict the result of a/d and b/d because d is never initialized, so line 31 has a chance to use garbage data.

Other things to point out:
-Your Fraction class is incomplete. You don't have a way to store the numerator and denominator, and the class interface is practically empty.
-The reduce function does not actually change the original values. You are passing by value, which means the parameter values are copied. What you are looking for is probably more similar to this:
1
2
3
4
5
6
7
 //Pass by reference, which allows you to modify the original variables
void reduce(int& numerator, int& denominator);

//...

int num(16), denom(120);
reduce(num, denom); //Now num and denom will change to 2 and 15, respectively 

Considering you have a Fraction class, it would probably be more beneficial (and more logical) to have one of the two functions:
1
2
void reduce(Fraction& fract); //Non-member (friend) function
void Fraction::reduce(); //Member function (simplify() sounds like a better name, though) 

-I think your reduce() function should be trivial since you have a gcd function. It makes little sense to copy-paste perfectly reusable code.
1
2
3
4
5
void reduce(int& numerator, int& denominator){
    const int divisor = GCD(numerator, denominator);
    numerator /= divisor;
    denominator /= divisor;
}
Last edited on
Topic archived. No new replies allowed.