Reducing Fractions with while loops

Hi, I am writing a program to reduce fractions to lowest terms... This is what I have so far, For some reason my while loop is repeating infinitely, When I take the loop away; it only reduces the fraction once (so that is not a solution). I do not understand why it is not working. Please lead me to my error.

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
int main()
{
    int x=1;
    char d;
    unsigned int numer, denom;
    
    
    cout<<"This program simplifys fractions"<<endl;
    cout<<"Enter a fraction (exp. 6/8): ";
    cin>>numer>>d>>denom;
    
    unsigned int newnumer=numer;
    unsigned int newdenom=denom;
    
    while(x!=0)
    {
    
       if(numer%2==0&&denom%2==0)
       {
       newnumer=newnumer/2;
       newdenom=newdenom/2;
       x=2;
       }
    
       else if(numer%3==0&&denom%3==0)
       {
       newnumer=newnumer/3;
       newdenom=newdenom/3;
       x=2;
       }
    
       else if(numer%5==0&&denom%5==0)
       {
       newnumer=newnumer/5;
       newdenom=newdenom/5;
       x=2;
       }
    
       else if(numer%7==0&&denom%7==0)
       {
       newnumer=newnumer/7;
       newdenom=newdenom/7;
       x=2;
       }
       
       x--;
    }
    
    cout<<newnumer<<"/"<<newdenom;
    
    getch();
    return 0;
}
First of all your x is 1 from initialization. 1 is different than 0 so the program enters in the while loop. If just one of these if-clauses condition is evaluated as true, the x gets the value 2. But until the next iteration, x gets the value 1 because it is decremented x--;. The program enters in an infinite loop because everytime one of these if-clauses conditon is evaluated as true so x has always the value 1. If the program doesn' t evaluate one of these if confition as true (so that x to get the value 2), x has the value 1 from the beginning of the while, until the x--; instruction so, finaly it gets the value 0 and the loop ends. You should think at the program in a different way.
but why is one of the if statements always true? I just can't fit it in my head.
Last edited on
I fix it. Take a look at it:
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
#include<iostream>
using namespace std;
int main()
{
    int x=1;
    char d;
    unsigned int numer, denom;


    cout<<"This program simplifys fractions"<<endl;
    cout<<"Enter a fraction (exp. 6/8): ";
    cin>>numer>>d>>denom;

    unsigned int newnumer=numer;
    unsigned int newdenom=denom;

    while(x!=0)
    {

       if((numer%2==0)&&(denom%2==0))
       {
       newnumer=newnumer/2;
       newdenom=newdenom/2;
       x=1;
       }


       else if((numer%3==0)&&(denom%3==0))
       {
       newnumer=newnumer/3;
       newdenom=newdenom/3;
       x=1;
       }

       else if((numer%5==0)&&(denom%5==0))
       {
       newnumer=newnumer/5;
       newdenom=newdenom/5;
       x=1;
       }

       else if((numer%7==0)&&(denom%7==0))
       {
       newnumer=newnumer/7;
       newdenom=newdenom/7;
       x=1;
       }

       x--;
    }

    cout<<newnumer<<"/"<<newdenom;


    return 0;
}
It only reduces once... exp. 12/16=6/8 while it should be 3/4. I need to reduce it to lowest terms.
Yes, I saw that one. I've modified it. Tell me how it works:
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
#include<iostream>
using namespace std;
int main()
{
    int x=1;
    char d;
    unsigned int numer, denom;


    cout<<"This program simplifys fractions"<<endl;
    cout<<"Enter a fraction (exp. 6/8): ";
    cin>>numer>>d>>denom;

    unsigned int newnumer=numer;
    unsigned int newdenom=denom;
    int i, k;
    while(x!=0)
    {

       if((numer%2==0)&&(denom%2==0))
       {  for(i=2; ((i<=numer)&&(i<=denom)); i=i+2)
          {
                 if((numer%i==0)&&(denom%i==0))
                 k=i;
                 else
                 break;
          }
          newnumer=newnumer/k;
          newdenom=newdenom/k;
       x=1;
       }


       else if((numer%3==0)&&(denom%3==0))
       {for(i=2; ((i<=numer)&&(i<=denom)); i=i+3)
          {
                 if((numer%i==0)&&(denom%i==0))
                 k=i;
                 else
                 break;
          }
       newnumer=newnumer/k;
       newdenom=newdenom/k;
       x=1;
       }

       else if((numer%5==0)&&(denom%5==0))
       { for(i=2; ((i<=numer)&&(i<=denom)); i=i+5)
          {
                 if((numer%i==0)&&(denom%i==0))
                 k=i;
                 else
                 break;
          }
       newnumer=newnumer/k;
       newdenom=newdenom/k;
       x=1;
       }

       else if((numer%7==0)&&(denom%7==0))
       {for(i=2; ((i<=numer)&&(i<=denom)); i=i+7)
          {
                 if((numer%i==0)&&(denom%i==0))
                 k=i;
                 else
                 break;
          }
       newnumer=newnumer/k;
       newdenom=newdenom/k;
       x=1;
       }

       x--;
    }

    cout<<newnumer<<"/"<<newdenom;


    return 0;
}
It still does not work with all fractions... never mind, i will just have to figure it out myself
1
2
3
4
5
6
if(numer%2==0&&denom%2==0)
{
  newnumer=newnumer/2;
  newdenom=newdenom/2;
  x=2;
}
You are checking against the original value.
Also 2 3 5 7 are not all the prime numbers.
Sorry, i am new... what does it mean to check against the original value?
Dude, when I was making your program I was in the car (driving with 140 mph) and when I entered 12/16 It worked. Give me an opposite example. If you enter numbers in the next interval: [0, 21] that program works perfectly, I think. If you want to do it more complex and flexible, make another if-clauses with the other prime numbers: 11, 13, 17, ...
Last edited on
ne555 is correct. That's the main reason for your infinite while loop. Suppose the fraction is 12/16 (Everyone's favorite by the looks of it)... numer and denom are divisible by 2. So you assign newnumer as 6 and newdenom as 8.
Now in the next iteration of the loop, numer is still 12, and denom is still 16!. It will again divide newnumer and newdenom by 2, so its now 3 and 4..
In iteration no. 3, it will again divide newnumer and newdenom by 2. Now your fraction becomes 1.5/2. Bit since they are ints, it gets rounded to 1 and 2. This does not matter. You see the problem? Always, 12 and 16 will be divisible by 2, hence your first 'if' will always be true, and hence x will always be assigned a new value, and will never go to 0.
If this is an assignment, and you strictly require the while loop, then make the changes as required, and add more conditions for higher prime numbers as ne555 said.
However if you want a better method, then find the GCD of the two numbers, divide number and denom both by the GCD, and voila, you're done...

Hope this helps... :)
I have found the solution!!! You can divide the two numbers by the GCF!!
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
int main()
{
    char d;
    unsigned int numer, denom;
    int GCF;
    float remain1, remain2;

    cout<<"This program simplifys fractions"<<endl;
    cout<<"Enter a fraction (exp. 6/8): ";
    cin>>numer>>d>>denom;




    if(numer>denom||numer==denom)
    {GCF=numer;}
    else if(numer<denom)
    {GCF=denom;}


    while(remain1 != 0 || remain2 != 0)
    {
        remain1=numer % GCF;
        remain2=denom % GCF;
        
        GCF--;
    }
    GCF=GCF+1;

    numer=numer/GCF;
    denom=denom/GCF;




    cout<<numer<<"/"<<denom;

    getch();
    return 0;
}
:D So my suggestion worked... Just another suggestion, there's a simpler way to find the GCF of two numbers, say numer and denom:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int num1, num2;

num1=numer;
num2=denom;

while (num1!=0)
{
	if(num2>num1)
		num2-=num1;
	else
		num1-=num2;
}

//num2 is your GCF. 
Topic archived. No new replies allowed.