-1

I have a homework that is all about computing the grade of a student. The formula is multiplying it by 30% then dividing by 100. I'm sure that I typed properly the code but when I run the program the answer is always zero.

int grade, s1,s2,s3,s4;
float average;

cout << "Enter grade in 1st quiz: ";
cin >> s1;
cout << "Enter grade in 2nd quiz: ";
cin >> s2;
cout << "Enter grade in 3rd quiz: ";
cin >> s3;
cout << "Enter grade in 4th quiz: ";
cin >> s4;

s1=(s1*=.30)/100;
s2=(s2*=.30)/100;
s3=(s3*=.20)/100;
s4=(s4*=.20)/100;

average = s1+s2+s3+s4;

cout << "Your average is " << average*100.0 << endl ; //average should not be zero.

I expect the ouput to be 80 to 90 but the actual output is always 0.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • 4
    Instead of the type int use the type float for the variables s1, s2, s3, and s4. – Vlad from Moscow Aug 31 '19 at 12:27
  • 1
    When you have integer division the result must be an integer so something like 47/100 is 0. – drescherjm Aug 31 '19 at 12:29
  • 3
    `(s1*=.30)` is an integer. – drescherjm Aug 31 '19 at 12:32
  • 1
    Do you know the difference between `s1=(s1*=.30)/100;` and the more usual `s1=(s1*.30)/100;`? What is your reason for doing it your way? – Yunnosch Aug 31 '19 at 12:33
  • Also `s1=(s1*=.30)/100` is undefined behavior in C++ **because you modify the same variable more than once in a single expression**. – Phil1970 Aug 31 '19 at 12:35
  • @Phil1970 I am not sure that "modify the same variable more than once in a single **expression**" is applicable here. I do not doubt twice within a **statement**, but expression? – Yunnosch Aug 31 '19 at 12:37
  • @Phil1970 isn't it well defined since C++17? – Aykhan Hagverdili Aug 31 '19 at 12:37
  • 2
    If variables are of type `int`, results stored to them will have integral values. So, if `s1 = 100` is entered, `s1 *= .3` will produce a result of about `30` (subject to rounding error since the calculation is done as floating point). If that result is divided by `100`, the result will always be zero (rounding is toward zero for positive values). Also, it is a really bad idea to modify a variable more than once in an expression. `s1 = (s1 *= .3)/100` modifies `s1` twice -> undefined behaviour (older standards) or unspecified behaviour (in some cases, in recent standards). – Peter Aug 31 '19 at 12:47
  • Well, even if the behavior might be defined in newer standard, it is still a bad idea to write it that way (less readable). And since `s1` is an integer, then you have truncation (doing the `*=`) and not the intended result anyway. – Phil1970 Aug 31 '19 at 12:50
  • 1
    @Yunnosch - the behaviour is mostly undefined if modifying a variable twice in an expression. In some cases, in more recent standards, there is some sequencing or the behaviour is unspecified. – Peter Aug 31 '19 at 12:50
  • 1
    Also assuming that `s1` to `s4` and `average` are number between 0 and 100, then you are essentially dividing twice by 100. So even if you were using floating point, the result would be 1% of the expected value. Thus in your example, you might get 1 if all notes are 100 (or above if some bonus are possible). You really want something like `int average = (s1 * 30 + s2 * 30 + s3 * 20 + s4 * 20) / 100;` with a possible `+50` if you want to round the final average. **That code is easier to read, correct and more efficient**. With than change remove `* 100` in `cout` statement. – Phil1970 Aug 31 '19 at 12:57

2 Answers2

0

In C++, the result of integer division is always an integer. You want those integers to be doubles or floats:

double grade, s1, s2, s3, s4;

This fixes the problem.

Also for calculations:

s1 = (s1 *= .30) / 100;

I am almost sure you meant:

s1 = (s1 * .30) / 100;
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
0

Either declare the variables s1, s2, s3 and s4 as having the type float or double or exclude these statements

s1=(s1*=.30)/100;
s2=(s2*=.30)/100;
s3=(s3*=.20)/100;
s4=(s4*=.20)/100;

and write instead

average = (s1 *.30)/100 + s2 *.30)/100 + (s3 * .20)/100 + ( s4 * .20)/100;

Otherwise there is a truncation in assignments like this

s1=(s1*=.30)/100;
 ^^^  ^^^

because s1 is an integer and there is a conversion from the type double to the type int.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335