Python ZeroDivisionError (tested)
ZeroDivisionError is Python refusing to divide any number by zero, which is mathematically undefined. Unlike some languages that silently produce infinity or NaN, Python always raises — even for floats. The exact message changes depending on the operator and type involved, which is useful for telling at a glance which line failed. We reproduced every common variant on a live interpreter.
1. Eight reproduced variants
| Code | Exact error (Python 3.13.5) |
|---|---|
5 / 0 | ZeroDivisionError: division by zero |
5.0 / 0 | ZeroDivisionError: float division by zero |
5 // 0 | ZeroDivisionError: integer division or modulo by zero |
5 % 0 | ZeroDivisionError: integer modulo by zero |
divmod(5, 0) | ZeroDivisionError: integer division or modulo by zero |
Decimal(5) / Decimal(0) | decimal.DivisionByZero: [<class 'decimal.DivisionByZero'>] |
Fraction(1,2) / 0 | ZeroDivisionError: Fraction(1, 0) |
0.0 / 0.0 | ZeroDivisionError: float division by zero |
The message text differs by operator (/ vs // vs %) and by operand type (int vs float), but every plain-Python case is some form of ZeroDivisionError. decimal.Decimal is the one exception: it raises its own DivisionByZero, which is actually a subclass of both ZeroDivisionError and ArithmeticError, so except ZeroDivisionError: still catches it.
2. Why 0.0 / 0.0 raises instead of giving NaN
In IEEE 754 floating point (the standard C, JavaScript, and many other languages use directly), 0.0 / 0.0 produces NaN and 5.0 / 0.0 produces inf, with no exception. Python deliberately overrides this and raises ZeroDivisionError for both cases instead, on the reasoning that a silent NaN propagating through a calculation is a worse outcome than failing loudly at the exact division that caused it.
>>> 0.0 / 0.0
ZeroDivisionError: float division by zero
>>> 5.0 / 0.0
ZeroDivisionError: float division by zero
If you specifically want IEEE 754 behavior (producing inf/nan instead of raising), use math.inf directly or construct it explicitly — plain division will not give it to you.
3. // and % fail together because they're related
Floor division and modulo both raise with the same underlying message for ints, because divmod() computes them as one operation internally:
>>> 5 // 0
ZeroDivisionError: integer division or modulo by zero
>>> 5 % 0
ZeroDivisionError: integer modulo by zero
>>> divmod(5, 0)
ZeroDivisionError: integer division or modulo by zero
If your code checks "is the divisor zero" before / but a different code path reaches % or // unchecked (a common bug when refactoring from one operator to another), you'll still hit this.
4. The fix: check before dividing, don't catch after
The clearest fix is a guard before the division, especially when zero is an expected input (e.g. an empty dataset, a rate with zero total requests):
def safe_divide(a, b, default=0):
if b == 0:
return default
return a / b
Use try/except ZeroDivisionError: instead when the divisor comes from a complex expression and checking it ahead of time would mean computing it twice:
try:
rate = successes / total_requests
except ZeroDivisionError:
rate = 0.0 # no requests yet, not a 0% rate
Catching ZeroDivisionError also transparently catches decimal.DivisionByZero, since it's a subclass — one except clause covers both int/float and Decimal math.
5. Common real causes
- Averages and rates over an empty collection.
total / len(items)whenitemsis empty. Checkif items:first. - Percentages computed before any data exists. A dashboard computing
completed / total * 100on day one, whentotalis still 0. - User input used directly as a divisor without validation (a denominator field, a scale factor).
- Normalizing by a range that collapses to zero, e.g.
(x - min_val) / (max_val - min_val)when every value in a dataset happens to be identical.
This is unrelated to ValueError: math domain error (raised by functions like math.sqrt(-1) or math.log(0) for a different reason: the input is out of the function's valid domain, not a division). Interestingly, math.fmod(5, 0) raises ValueError: math domain error rather than ZeroDivisionError, because math module functions generally report invalid-domain input that way regardless of whether division is involved. If the error instead comes from indexing past the end of a list, see IndexError: list index out of range.
Frequently asked questions
Why does Python raise ZeroDivisionError for 0.0/0.0 instead of returning NaN?
Python deliberately differs from IEEE 754 float behavior here. Languages like C or JavaScript return NaN/Infinity silently; Python raises ZeroDivisionError for both 0.0/0.0 and 5.0/0.0 so the failure is caught at the exact line that caused it, instead of a NaN silently propagating through later calculations.
What is the difference between the ZeroDivisionError messages for / and //?
They come from different C-level code paths: 5/0 gives 'division by zero' (or 'float division by zero' for floats), while 5//0 and 5%0 give 'integer division or modulo by zero' or 'integer modulo by zero'. All are the same exception type, just different text.
Does decimal.Decimal raise ZeroDivisionError too?
It raises decimal.DivisionByZero, which is a subclass of both ZeroDivisionError and ArithmeticError. A plain except ZeroDivisionError: still catches it, so you don't need a separate except clause for Decimal math.
How do I safely divide without crashing on a zero denominator?
Check the divisor first (if denominator == 0: return default) when zero is an expected, normal input. Use try/except ZeroDivisionError when the divisor comes from an expression you don't want to evaluate twice.
Is ZeroDivisionError the same as a math domain error?
No. ZeroDivisionError is specifically about dividing by zero (/, //, %, divmod()). ValueError: math domain error comes from math module functions given input outside their valid range, like math.sqrt(-1) or math.log(0) - a different problem that happens not to involve a stray zero denominator.
Written with AI assistance. Measured on 2026-10-03 with Python 3.13.5 on Linux using plain python3 one-liners. Every error below is copy-pasted output, not paraphrased. PlainHeaders is our extension; Python is free.