Using a do-while loop to validate input

I'm having trouble with this program. It produces the correct sample output given to me by my professor, but apparently it must not work all the time because when I submit it to the Unix grader it causes an infinite loop. Can someone tell me what I'm doing wrong?

Here are the exact directions:
Function: Use input validation to read two decimal numbers, A and B,
which must satisfy the rule that the larger number must be
over 20% greater than the smaller number.
Use the prompt "PCT2: ".
Display the validated inputs, A and B with ONE decimal place.

Example: Input: 4 20 ==> Output: PCT2: 4.0 20.0
Input: 20.0 24.0 33 51 ==> Output: PCT2: PCT2: 33.0 51.0


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
   cout << endl; //DO NOT MODIFY, MOVE or DELETE

   float A, B;

   do
   {
    cout << "PCT2: "; cin >> A >> B;
   } while(abs(B-A)/B <= 0.2);




   cout << fixed << setprecision(1) << A << " " << B;
   cout << endl; return 0; //DO NOT MODIFY, MOVE or DELETE
}
Im not quite sure about the amount of times you want to enter values? Should it keep on going with calculations and outputs until you close the program? And where is the rest of the program?

If you want to be able to jump out of the calculationloop whenever you want, make an extra condition:

while(abs(B-A)/B <= 0.2 && input !=0);.

But im not really sure of how the program should work (the amount of inputs and calculations you want to do).
The program should continue to run, taking in inputs as long as the second number is less than or equal to 20% greater than the first number. When the second number is more than 20% greater than the previously entered number, the program must print out those two values and stop running.
Last edited on
Ok so i think the problem is that both A and B can be the BIGGEST number, and not only the SECOND one. You need to make sure before calculating which one is bigger.

1
2
3
4
5
6
7
8
9
if(A>B)
{
    //do this
}
else
{
    //do that
}


Are you with me? U can never take for granted that the second input will always be the largest one. The assignment says " Use input validation to read two decimal numbers, A and B,
which must satisfy the rule that the larger number must be
over 20% greater than the smaller number."
Ok, I understand what you're saying. I'm just not sure how to integrate the if-else into my code and still keep the do-while loop running.
Actually i think you can just demand the second condition (which is if A is bigger) in your while statement.

 
while(abs(B-A)/B <= 0.2 || abs(A-B)/A <= 0.2);


now one of these conditions have to be true, B or A must apply to the rules. If none of them does that, while(false) will be the case and your loop should end.
Ok, I tried that and it seems to work as expected. (I enter "20 4", the output is "PCT2: 20.0 4.0"). For some reason the grader is still infinitely looping though.
Ok i dont have any compiler atm so i can't try it out. What exactly do you mean with the grader is still infinitely looping ?
We have a grader program that we submit our programs to that tells us if we got the program right or not. When I submit mine, the grader tells me neither right nor wrong and instead just freezes. My professor told me that this is because my program is somehow creating an infinite loop with the sample input given from the grader.
while(abs(B-A)/B <= 0.2 || abs(A-B)/A <= 0.2);

I believe that this should be &&.
@fg109 I just tried that and it produced "PCT2: 20.0 24.0" instead of "PCT2: PCT2: 33.0 51.0" when I entered "20.0 24.0 33 51".
while(abs(B-A)/B <= 0.2 || abs(A-B)/A <= 0.2);

I believe that this should be &&.


Hmm, Im not sure if it's me thinking very wrong right now, but && would require that both A && B follow the rules at the same time. But it's only A || B that need to apply to the rules.

while(x/y >5 || y/x >5)

while(x/y >5 && y/x >5) // 20/2 and 2/20 can never be true together
His goal is to stop looping once either of the numbers is over 20% larger than the other.

abs(B-A)/B <= 0.2

^ This part is true as long as A is not at least 21% larger than B.

abs(A-B)/A <= 0.2

^ This part is true as long as B is not at least 21% larger than A.

while(abs(B-A)/B <= 0.2 || abs(A-B)/A <= 0.2);

^ This means as long as (A is not at least 21% larger than B) or (B is not at least 21% larger than A), then keep looping.

So let's say that A == 100 and B == 121. Just from looking at it we know that B is 21% larger than A.

abs(B-A)/B is abs(121 - 100) / 121 which is 0.17, smaller than 0.2, making abs(B-A)/B <= 0.2 be true.

abs(A-B)/A is abs(100 - 121) / 100 which is 0.21, greater than 0.2, making abs(B-A)/B <= 0.2 be false.

The while statement is while (true || false), which is the same as while (true).



@fg109 I just tried that and it produced "PCT2: 20.0 24.0" instead of "PCT2: PCT2: 33.0 51.0" when I entered "20.0 24.0 33 51".

That's because floating point numbers aren't 100% accurate. You might try to divide 1.0 by 4.0 and get 0.249999999. You can try using double instead of float variables and see if that helps.
Last edited on
Yeah i noticed i missunderstood. I thought we wanted the while loop to keep on going, but we don't :P

I thought somehow that we had some kind of of conditions breaking us out of the loop but yeah, thats the while-statements' job yeah xD


^ Is right and && is the correct way to go here. I don't have a compiler so i couldn't trail n error either xD
(abs(B-A)/B <= 0.2 || abs(A-B)/A <= 0.2) (abs(B-A)/B <= 0.2 && abs(A-B)/A <= 0.2)

^ The two are pretty close. I tried to make an example program to prove that one worked and the other didn't using a loop and some random number generation but it didn't work that well.

The two statements give exactly the same results except when one number is larger than another by 20% to 25% (the range (0.2, 0.25]).
Last edited on
It finally worked! Thanks a lot to both of you for all your help.
Topic archived. No new replies allowed.