Exercise 3-6
The average-grade computation in §3.1/36 might divide by zero if the student didn’t enter any grades. Division by zero is undefined in C++, which means that the implementation is permitted to do anything it likes. What does your C++ implementation do in this case? Rewrite the program so that its behavior does not depend on how the implementation treats division by zero.
Solution
Before changing any codes, let me try running the program like this:
- Test 1: do not supply any grades at all.
- Test 2: supply mid-term and final-exam grades, but not supply the homework grades.
Test 1
Please enter your first name: Johnny Hello, Johnny! Please enter your midterm and final exam grades: ^Z Enter all your homework grades, followed by end-of-file: Your final grade is nan
Test 2
Please enter your first name: Johnny Hello, Johnny! Please enter your midterm and final exam grades: 80 90 Enter all your homework grades, followed by end-of-file: ^Z Your final grade is nan
In both tests, because of the fact that I did not specify any homework grades, when the program tries to compute the average homework grade, it bump into division by zero. In my case, I ran the test via the Code::Block IDE on a Windows Vista machine, the undefined output is nan. (i.e. Not A Number).
To avoid this add an if statement to condition-check the value of count. If count is zero, exit the code peacefully with a message saying “Cannot compute final grade due to missing grades supplied – ensure you supply all grades as required.” Something like that.
if (count == 0) { cout << "Cannot compute final grade due to missing grades supplied - ensure you supply all grades as required." << endl; return 1; }
The full code looks like this:
#include <iomanip> #include <ios> #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::setprecision; using std::string; using std::streamsize; int main() { // ask for and read the student's name cout << "Please enter your first name: "; string name; cin >> name; cout << "Hello, " << name << "!" << endl; // ask for and read the midterm and final grades cout << "Please enter your midterm and final exam grades: "; double midterm, final; cin >> midterm >> final; // ask for the homework grades cout << "Enter all your homework grades, " "followed by end-of-file: "; // the number and sum of grades read so far int count = 0 ; double sum = 0.0; // a variable into which to read double x; // invariant: // we have read count grades so far, and // sum is the sum of the first count grades // after entering the last value, hit the F6 button, then enter (to indicate end of file) // or hit Ctrl+z, then enter. while (cin >> x) { ++count; sum += x; } double dummy = count; // for some reason the code fails unless I add this line. if (count == 0) { cout << "Cannot compute final grade due to missing grades supplied - ensure you supply all grades as required." << endl; return 1; } // write the result streamsize prec = cout.precision(); cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * sum / count << setprecision(prec) << endl; return 0; }
Result
Please enter your first name: Johnny Hello, Johnny! Please enter your midterm and final exam grades: ^Z Enter all your homework grades, followed by end-of-file: Cannot compute final gr ade due to missing grades supplied - ensure you supply all grades as required.