simple grade program no errors but wont work correctly

Pages: 12
i am trying to make the if statement really long just so i can practice. I compile it with 0 errors but when i input 99.8 it just spits out "input grade" it doesnt print the GPA, so my question is why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# include <iostream>
using namespace std;

int main ()
{
float grade;

 do
{
   cout << "Enter your grade";
   cin >> grade;
if (grade <= 100 && grade >= 99.9)
   cout << "GPA = 4.0  \n\n";
else if (grade <= 99.8 && grade >= 99.7)
   cout << "GPA = 3.9 \n\n";
else if (grade <= 99.6 && grade >= 99.5)
   cout << "GPA = 3.8 \n\n";
else if (grade <= 99.4 && grade >= 99.3)
   cout << "GPA = 3.7 \n\n";
else if (grade <= 99.2 && grade >= 99.1)
   cout << "GPA = 3.6 \n\n";
}
while (grade < 100 && grade > 0);
    return 0;

Floats aren't much precise, so your 99.8 may be a bit different from the 99.8 you have in the if
Let's say your input gives 'grade' a value of 99.80001 (this is just an example)

1
2
3
4
if (grade <= 100 && grade >= 99.9) // not matched, 99.80001 < 99.9
   //...
else if (grade <= 99.8 && grade >= 99.7) // not matched, 99.80001 > 99.8
  //... 


Your ifs don't handle all the cases, you will lose many numbers:
(99.9,99.8) ∪ (99.7,99.6) ...
so how do i fix that?
i guess i should say round to the nearest tenth
but how do i tell the computer to do this? is there another function other than float or int i can use?
You can use an arbitrary precision library, fixed point numbers or just read integers ( 998 = 99.8 )
is there any way i could go out to a certain number of decimal points so it would work?

1
2
3
4
else if (grade <= 99.80001 && grade >= 99.70001)
   cout << "GPA = 3.9 \n\n";
else if (grade <= 99.60001 && grade >= 99.50001)
   cout << "GPA = 3.8 \n\n";


or would that not work?
Another thing to note here is that you don't need to have an upperbound. It's unnecessary here because higher values are impossible due to the above ifs in the chain:

1
2
3
4
5
6
7
if(grade <= 100)
{
  if(grade >= 99.9)
    cout << "GPA = 4.0\n\n";
  else if(grade >= 99.7)
    cout << "GPA = 3.9\n\n";
  ...


Note the else in the above guarantees that the previous if was false -- ie, grade is < 99.9 (or is NaN -- but that's another topic). So you don't need to check if <= 99.8
Last edited on
wow, talk about grading on a curve! lol :)
strange, this is another instance where the Visual Studio Express compiler differs from the Watcom compiler. I was getting the same problem as described above with the VS compiler, but when I compiled it with Watcom, the 99.8 input, output the 3.9 GPA with no issues. I am really beginning to wonder about the quirks with VS Express.
Last edited on
That is not a problem coming from the compiler, it derives from the floating point imprecision
bazzy can you elaborate a bit? I believe you , but i would like to know the how of it
thanks bazzy that was EXTREMELY informative! I got it now
Last edited on
Just a small correction, but floating point values are not imprecise. They exact values. It's floating point operations (including stringization) that are imprecise.
i am confused to how a the operations could complicate what seems very simple, 99.8 >= 99.8 therefore the output should be 3.9.

so how can i switch the operations to fix this problem?
thanks guys im really enjoying c++
Last edited on
What you need to realize is that floating point numbers are approximated. 99.8 might not actually be 99.8, but might be 99.799999999.
I changed the base type to a double float and it worked fine, while it wont solve the float problem it will get you by in this instance it seems. try that. good luck.


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

# include <iostream>
using namespace std;

int main ()
{
double grade;

 do
{
   cout << "Enter your grade";
   cin >> grade;
if (grade <= 100 && grade >= 99.9)
   cout << "GPA = 4.0  \n\n";
else if (grade <= 99.8 && grade >= 99.7)
   cout << "GPA = 3.9 \n\n";
else if (grade <= 99.6 && grade >= 99.5)
   cout << "GPA = 3.8 \n\n";
else if (grade <= 99.4 && grade >= 99.3)
   cout << "GPA = 3.7 \n\n";
else if (grade <= 99.2 && grade >= 99.1)
   cout << "GPA = 3.6 \n\n";
}
while (grade < 100 && grade > 0);

return 0;
}
Don't do that.

What you're trying to do is flawed.

there are numbers between 99.8 and 99.9. Because floating points are approximate, odds are good that you'll end up with one of those numbers and not 99.8 and 99.9 exactly.

Just because it works in this instance doesn't mean you should do it. This is a bad move.

See my earlier post. There's no reason to have upper and lower bounds for each if statement. The 'else' already rules out the previous ranges:

1
2
3
4
5
6
7
if(grade <= 100)
{
  if(grade >= 99.9)
    cout << "GPA = 4.0\n\n";
  else if(grade >= 99.7)  // no need for 99.8 here, above if already rules it out!
    cout << "GPA = 3.9\n\n";
  ...
even if i dont use upper and lower bounds when i run the program and input 99.7 it doesnt output anything.

what could i do instead of float or double float? i dont want to use intergers because that is not what grades are commonly given.

if even tried

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
#include <iostream>
using namespace std;

int main ()
{
float i;


{
  cout << "Enter Grade= " ;
  cin>> i ;
if (i ==100 )
  cout << "GPA= 4.0 ";
else if (i ==99.8  )
  cout << "GPA= 3.99 ";
else if (i == 99.6 )
  cout << "GPA= 3.98 ";
else if (i == 99.4 || i ==99.3)
  cout << "GPA= 3.97 ";
else if (i == 99.2 || i ==99.1)
  cout << "3.96 ";
else if (i <= 99.0)
  cout << "not done" ;
}
while (i <= 100 && i >= 59.5);
 return 0;
}


and it still wont work. How is it possible that i input 99.3 and it equals 99.3 but wont output anything?

sorry i am new at this and am not quite understanding
Aye ya... floating point values are APPROXIMATE.

99.3 is not necessarily 99.3. The closest thing the computer might be able to represent is something like 99.3000000001, which is very close to 99.3, but does not equal 99.3.

Therefore if you do i == 99.3 this will likely fail even if you input 99.3, because it might not be exactly 99.3.

Stick with ranges.

Again... See my earlier post... I'll try to give it more detail this time:

1
2
3
4
5
6
7
8
9
if(grade <= 100)
{
  // if you reach here, grade is guaranteed to be <= 100
  if(grade >= 99.9)   // therefore, if >= 99.9, that means you're between 99.9 and 100
    cout << "GPA = 4.0\n\n";
  else   // this else ties to the above if, which means that grade must be < 99.9 to proceed
    if(grade >= 99.7)  // No need for upper bound here, because it's already sure that you're < 99.9
    cout << "GPA = 3.9\n\n";
  ...  // etc 

Last edited on
Disch's solution is the most effective and efficient resolution to this anomaly
Pages: 12