How to fix this loop so the calculations do not effect the NEXT set of numbers?

Mar 27, 2017 at 11:41pm
Question 1: If you input the grades of 93, -1, 97 90.. The average should be (93+97+90)/3 = 93.33, but it is displaying the average as 93.00, all the decimals are rounding to .00 ... Why?

Question 2: If I enter 'Y' to calculate the average of the next student & continue the loop, it's including the calculations from the previous students test grades. How do I stop that from happening? I need the NEW average for the NEW set of test grades. I'm very new at loops and I'm a loss! Any tips or hints to lead me in the right direction will be very appreciated!! THANK YOU!

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
	int scores, stuID, testScore, exAbs = 0, total = 0;
	char choice, grade;
	double avg = 0;

	//Ask user number of test scores
	cout << "Enter the number of scores for this semester: ";
	cin >> scores;

	//Begin OUTER loop
	do
	{
		cout << "=====================================================\n";
		cout << "Enter a student's ID: ";
		cin >> stuID;


		//Test scores
		for (int i = 1; i <= scores; i++)
		{
			cout << "Enter a score: ";
			cin >> testScore;

			//Calculate average
			if (testScore == -1)
			{
				exAbs++;
			}
			else
			{
				total = total + testScore;
				avg = (total) / (scores - exAbs);
			}


		}

		//Determine letter grade
		{
			if (avg >= 90)
			{
				grade = 'A';
			}
			else if (avg < 90 && avg >= 80)
			{
				grade = 'B';
			}
			else if (avg < 80 && avg >= 70)
			{
				grade = 'C';
			}
			else if (avg < 70 && avg >= 60)
			{
				grade = 'D';
			}
			else if (avg < 60 && avg >= 0 && exAbs <= 1)
			{
				grade = 'F';
			}
			else if (exAbs >= 2)
			{
				grade = 'I';
			}
		}

		//Display ID, Avg, & Letter Grade
		if (exAbs >= 2)
		{
			cout << "ID=" << stuID << " ";
			cout << "Excused=" << exAbs << " ";
			cout << "Grade=" << grade << endl;
			cout << "=====================================================" << endl;
		}
		else if (exAbs <= 1)
		{
			{
			cout << "ID=" << stuID << " ";
			cout << "Avg=" << fixed << setprecision(2) << avg << " ";
			cout << "Grade=" << grade << endl;
			cout << "=====================================================" << endl;
			}
		}

		//Ask user to continue loop
		cout << "Add a student (Y to continue, any other character to end): ";
		cin >> choice;
	} while (choice == 'Y' || choice == 'y');



	system("pause");
	return 0;
}
Mar 27, 2017 at 11:59pm
The average should be (93+97+90)/3 = 93.33, but it is displaying the average as 93.00, all the decimals are rounding to .00 ... Why?


Integer division :+)

Question 2: If I enter 'Y' to calculate the average of the next student & continue the loop, it's including the calculations from the previous students test grades. How do I stop that from happening?


Reset those variables.

Good Luck !!
Mar 28, 2017 at 12:30am
Ohhhh ok, I understand. I moved testScore = 0, exAbs = 0, total = 0; inside of my loop to reset. That makes since... Thank You!!!! What about the division though? I have always used fixed << setprecision(2) and it has always rounded correctly. I don't understand why it's not cooperating this time?
Mar 28, 2017 at 12:33am
What about the division though?


With integer division: 1/2 is zero. Look at your code see where you have integer division. What do you need to do to avoid it?
Mar 28, 2017 at 12:41am
OH I had testScore = 0, exAbs = 0, total = 0 stored as an integer. I changed it as a double... That was an oversight. LoL. Thanks for the tips and letting me figure it out!
Mar 28, 2017 at 12:57am
If the scores have to be int (ideally unsigned int - they shouldn't be negative) then one can do things like this to promote the expression to double:

avg = (total * 1.0) / (scores * 1.0 - exAbs );

although that is messy :+(

The classic way is to cast the values to the desired type:

1
2
double TotalAsDouble = static_cast<double>(total); 
double ScoreAsDouble = static_cast<double>(scores);  // NumOfScores  a better name? 


Then use them in a later expression.

This:
total = total + testScore;

can be written:
total += testScore;

Last edited on Mar 28, 2017 at 12:58am
Topic archived. No new replies allowed.