Java ArithmeticException: / by zero — Integer Division Trap
Fix "/ by zero" ArithmeticException by guarding integer divisors, distinguishing integer from floating-point division, and handling empty aggregates.
Symptoms
- java.lang.ArithmeticException: / by zero
- The same expression with doubles returns Infinity instead of throwing
- Average or percentage functions fail on empty input
Possible causes
- Integer division or remainder uses a divisor that can be zero
- An average is computed over an empty collection whose size is zero
- Integer modulo by a variable that is zero on some path
Diagnosis steps
Reproduce the integer division
jshell -q <<'EOF'
try { int r = 10 / 0; } catch (ArithmeticException e) { System.out.println(e); }
EOFInterpretation
Integer division throws; double division of 10.0/0 yields Infinity, proving the type matters.
Check the divisor at the call site
grep -rn "/ [a-zA-Z].*size()\|% .*count" src/main/javaInterpretation
Auditing divisors that come from sizes or counts finds the unguarded path.
Root cause
Integer division and remainder by zero are undefined and throw ArithmeticException. Floating-point division by zero instead yields NaN or Infinity per IEEE 754, so the bug is specific to integral arithmetic.
Fix
Guard the divisor before dividing, return a defined sentinel for empty aggregates, and choose double deliberately when Infinity or NaN semantics are acceptable.
Risk note
Returning 0 for an undefined average can be misread; return OptionalDouble.empty() to signal absence.
Verify the fix
Rerun with a zero divisor and confirm no exception and the expected sentinel; add tests for zero and nonzero divisors.
Symptoms
This guide profiles the failure behind “Java ArithmeticException: / by zero — Integer Division Trap”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.
Observed symptoms include:
- java.lang.ArithmeticException: / by zero
- The same expression with doubles returns Infinity instead of throwing
- Average or percentage functions fail on empty input
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Reproduce the integer division
jshell -q <<'EOF'
try { int r = 10 / 0; } catch (ArithmeticException e) { System.out.println(e); }
EOF
Integer division throws; double division of 10.0/0 yields Infinity, proving the type matters.
Step 2: Check the divisor at the call site
grep -rn "/ [a-zA-Z].*size()\|% .*count" src/main/java
Auditing divisors that come from sizes or counts finds the unguarded path.
Likely contributors, in order of frequency:
- Integer division or remainder uses a divisor that can be zero
- An average is computed over an empty collection whose size is zero
- Integer modulo by a variable that is zero on some path
Root Cause
Integer division and remainder by zero are undefined and throw ArithmeticException. Floating-point division by zero instead yields NaN or Infinity per IEEE 754, so the bug is specific to integral arithmetic.
The Fix
Guard the divisor before dividing, return a defined sentinel for empty aggregates, and choose double deliberately when Infinity or NaN semantics are acceptable.
Watch out: Returning 0 for an undefined average can be misread; return OptionalDouble.empty() to signal absence.
public static OptionalDouble average(int[] values) {
if (values.length == 0) return OptionalDouble.empty(); // no division
long sum = 0;
for (int v : values) sum += v;
return OptionalDouble.of((double) sum / values.length);
}
int divisor = 0;
int safe = divisor == 0 ? 0 : 100 / divisor; // guarded
Verify and Prevent
Rerun with a zero divisor and confirm no exception and the expected sentinel; add tests for zero and nonzero divisors.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.