Integer Division in a Grade Averaging Utility
A student writes a helper class GradeTool with this method:
public static int average(int total, int count) {
return total / count;
}
In main, the student calls average(17, 5) and prints the result, expecting 3.4. Instead the program prints 3. The student then tries average(17, 5) * 100 / 5 to get a percentage and is surprised again. A teammate insists the fix is to change the parameter types to double, but the student wants to keep int parameters because scores are whole numbers. Later, a test calls average(0, 0) and the program crashes with ArithmeticException.
1. Explain why `average(17, 5)` returns 3 and why `average(17, 5) * 100 / 5` does not produce the percentage the student expects. What single change keeps the `int` parameters but yields a correct truncated average?
Read the worked answer
Both operands of / are int, so Java performs integer division: 17 / 5 truncates toward zero and yields 3. The fractional part is discarded, not rounded.
For the percentage, evaluation is left-to-right: average(17,5) returns the int 3, then 3 * 100 is 300 (int), then 300 / 5 is 60. The rounding loss happened before the multiplication, so the error is amplified. The student wanted (17.0/5)*100/5 style math, but the truncation is baked in.
To keep int parameters and get a correct truncated average, cast before dividing:
return (int) ((double) total / count);
or, if only the integer quotient is wanted, the original is already correct - the bug is the expectation, not the code. The key judgment: integer division is fine when you want a whole-number quotient; it is wrong when you need a real-valued average.
2. The call `average(0, 0)` throws `ArithmeticException`. Describe the exception and explain how the student should guard against it without changing the method signature.
Read the worked answer
ArithmeticException is an unchecked exception thrown at runtime when an integer division has a zero divisor. It is not a compile error, so the program compiles and only fails when that line executes.
A guard keeps the signature intact:
public static int average(int total, int count) {
if (count == 0) {
return 0; // or throw IllegalArgumentException with a message
}
return total / count;
}
The judgment call is what count == 0 means. Returning 0 silently hides a caller bug; throwing IllegalArgumentException documents the contract. Either is defensible, but the student must choose deliberately rather than let an ArithmeticException leak out with a message that does not explain the real problem (an empty data set).