TheAlgorithms/Python · error · ValueError
math domain error
Error message
math domain error
What it means
Raised by gamma_iterative in maths/gamma.py when num <= 0. The function approximates the Gamma function via numerical integration of exp(-x)*x^(z-1) from 0 to infinity, which diverges for non-positive z, so the code explicitly mirrors CPython's math.gamma by raising ValueError('math domain error'). This is a precondition check at the top of the function, before scipy's quad is called.
Source
Thrown at maths/gamma.py:45
>>> gamma_iterative(0)
Traceback (most recent call last):
...
ValueError: math domain error
>>> gamma_iterative(9)
40320.0
>>> from math import gamma as math_gamma
>>> all(.99999999 < gamma_iterative(i) / math_gamma(i) <= 1.000000001
... for i in range(1, 50))
True
>>> gamma_iterative(-1)/math_gamma(-1) <= 1.000000001
Traceback (most recent call last):
...
ValueError: math domain error
>>> gamma_iterative(3.3) - math_gamma(3.3) <= 0.00000001
True
"""
if num <= 0:
raise ValueError("math domain error")
return quad(integrand, 0, inf, args=(num))[0]
def integrand(x: float, z: float) -> float:
return math.pow(x, z - 1) * math.exp(-x)
def gamma_recursive(num: float) -> float:
"""
Calculates the value of Gamma function of num
where num is either an integer (1, 2, 3..) or a half-integer (0.5, 1.5, 2.5 ...).
Implemented using recursion
Examples:
>>> from math import isclose, gamma as math_gamma
>>> gamma_recursive(0.5)
1.7724538509055159
>>> gamma_recursive(1)View on GitHub (pinned to f5988cc097)
Solutions
- Only call gamma_iterative with strictly positive arguments (num > 0).
- If negative or zero inputs are legitimate in your domain, switch to a library that supports Gamma's analytic continuation or reflection formula (e.g. scipy.special.gamma handles negatives at non-integers; use math.gamma only for num > 0).
- Guard call sites: validate num > 0 before calling and branch to your own handling otherwise.
Example fix
// before
val = gamma_iterative(x) # x may be <= 0
// after
if x <= 0:
raise ValueError(f"gamma_iterative requires num > 0, got {x}")
val = gamma_iterative(x) Defensive patterns
Strategy: validation
Validate before calling
def safe_gamma_iterative(num: float) -> float:
if num <= 0:
raise ValueError(f"gamma defined only for num > 0, got {num}")
return gamma_iterative(num) Type guard
def is_positive_real(num) -> bool:
return isinstance(num, (int, float)) and num > 0 Try / catch
try:
val = gamma_iterative(x)
except ValueError as e:
if 'domain' in str(e):
# handle non-positive input
...
raise Prevention
- Treat num > 0 as a hard precondition wherever gamma_iterative is used
- Filter zeros and negatives out of input arrays before batch processing
When it happens
Trigger: Calling gamma_iterative with num = 0 or any negative value, e.g. gamma_iterative(-1) or gamma_iterative(0). Any num <= 0 hits the 'if num <= 0' branch and raises immediately.
Common situations: Porting code from math.gamma and assuming different domain rules; passing user-supplied or computed values (e.g. shifted by a subtraction) that can reach 0 or below; looping over ranges that include 0 without filtering.
Related errors
- surface_area_cube() only accepts non-negative values
- surface_area_cuboid() only accepts non-negative values
- surface_area_sphere() only accepts non-negative values
- surface_area_hemisphere() only accepts non-negative values
- surface_area_cone() only accepts non-negative values
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/df2a1c717a816bef.
Report an issue: GitHub.