EnterpriseQualityCoding/FizzBuzzEnterpriseEdition · error · ArithmeticException
An attempt was made to divide by zero.
Error message
An attempt was made to divide by zero.
What it means
This is the IntegerDivider from the FizzBuzz Enterprise Edition satire codebase. Before dividing, it explicitly checks whether the denominator equals zero (via IntegerForEqualityComparator against Constants.INTEGER_DIVIDE_ZERO_VALUE) and throws a plain java.lang.ArithmeticException with the message 'An attempt was made to divide by zero'. Although the actual quotient is computed with doubles (which would yield Infinity/NaN rather than throw), the library chooses to fail fast with the classic exception instead of propagating non-finite values.
Source
Thrown at src/main/java/com/seriouscompany/business/java/fizzbuzz/packagenamingpackage/impl/math/arithmetics/IntegerDivider.java:43
*/
@Autowired
public IntegerDivider(final FirstIsLargerThanSecondDoubleComparator firstIsLargerThanSecondDoubleComparator,
final FirstIsSmallerThanSecondDoubleComparator firstIsSmallerThanSecondDoubleComparator) {
super();
this.firstIsLargerThanSecondDoubleComparator = firstIsLargerThanSecondDoubleComparator;
this.firstIsSmallerThanSecondDoubleComparator = firstIsSmallerThanSecondDoubleComparator;
}
/**
* @param nFirstInteger int
* @param nSecondInteger int
* @return int
*/
public int divide(final int nFirstInteger, final int nSecondInteger) {
final boolean denominatorEqualsZero =
IntegerForEqualityComparator.areTwoIntegersEqual(nSecondInteger, Constants.INTEGER_DIVIDE_ZERO_VALUE);
if (denominatorEqualsZero) {
throw new ArithmeticException(Constants.AN_ATTEMPT_WAS_MADE_TO_DIVIDE_BY_ZERO);
} else {
final double dbFirstNumber = IntToDoubleConverter.Convert(nFirstInteger);
final double dbSecondNumber = IntToDoubleConverter.Convert(nSecondInteger);
final double dbQuotient = dbFirstNumber / dbSecondNumber;
double dbRoundedQuotient = (double) Constants.INTEGER_ORIGIN_ZERO_VALUE;
if (this.firstIsSmallerThanSecondDoubleComparator.FirstIsSmallerThanSecond(dbQuotient,
(double) Constants.INTEGER_ORIGIN_ZERO_VALUE)) {
dbRoundedQuotient = Math.ceil(dbQuotient);
} else if (this.firstIsLargerThanSecondDoubleComparator.FirstIsLargerThanSecond(dbQuotient,
(double) Constants.INTEGER_ORIGIN_ZERO_VALUE)) {
dbRoundedQuotient = Math.floor(dbQuotient);
}
final int nIntegerQuotient = DoubleToIntConverter.Convert(dbRoundedQuotient);
return nIntegerQuotient;
}
}
}View on GitHub (pinned to 4922c077c0)
Solutions
- Check the denominator before calling divide() and decide policy (skip, clamp, or report) at the call site.
- If a zero denominator is expected input, guard the caller: if (denominator == 0) { /* handle */ } else { divider.divide(num, denominator); }
- If the value comes from config (loop range), validate the configuration at startup so Constants/range values cannot be zero.
- As a last resort, wrap the call in try { ... } catch (ArithmeticException e) { ... } — but pre-checking is cleaner since the condition is trivially testable.
Example fix
// before
final int quotient = this.integerDivider.divide(numerator, denominator);
// after
if (denominator == 0) {
throw new IllegalArgumentException("denominator must be non-zero");
}
final int quotient = this.integerDivider.divide(numerator, denominator); Defensive patterns
Strategy: validation
Validate before calling
// Run before IntegerDivider.divide(...)
if (nSecondInteger == 0) {
// choose your policy: skip, clamp, or fail with context
throw new IllegalArgumentException("denominator must be non-zero, got: " + nSecondInteger);
}
final int result = integerDivider.divide(nFirstInteger, nSecondInteger); Try / catch
// Only as a boundary guard around third-party-driven denominators
try {
final int q = integerDivider.divide(n, d);
} catch (ArithmeticException e) {
if (!"An attempt was made to divide by zero.".equals(e.getMessage())) throw e;
logger.warn("Skipped zero-denominator division for n={}", n);
} Prevention
- Validate denominators at the call site before divide(); the check is one == comparison.
- Validate loop-range/config constants at startup so denominators derived from them can never be zero.
- Never rely on the double-division inside the library to 'absorb' zero — this implementation fails fast on purpose.
- Centralize division in one wrapper that enforces the zero-check policy, instead of checking at every call site.
When it happens
Trigger: Calling IntegerDivider.divide(nFirstInteger, nSecondInteger) (injected via its constructor with the two DoubleComparators) with nSecondInteger == 0, e.g. divide(15, 0) or divide(0, 0). The equality comparator compares nSecondInteger to Constants.INTEGER_DIVIDE_ZERO_VALUE (0); any other denominator proceeds to double division.
Common situations: In this codebase the divider is used by LoopComponent/@Invalid gitBranchList currentStepRange computations where the loop range (nFizzBuzzLow, nFizzBuzzHigh) is derived from configuration: a zero FizzBuzzHigh (or a misconfigured range constant) makes every loop iteration hit this. Generally: computing ratios/percentages from a denominator that can legitimately be zero (counts, totals, batch sizes) without pre-checking.
Related errors
AI-assisted analysis of EnterpriseQualityCoding/FizzBuzzEnterpriseEdition@4922c077c0 (2026-08-14).
Data as JSON: /api/errors/00635d53dcc493ce.
Report an issue: GitHub.