TheAlgorithms/Python · error · ValueError
double_factorial_recursive() only accepts integral values
Error message
double_factorial_recursive() only accepts integral values
What it means
Raised by double_factorial_recursive() in maths/double_factorial.py when n is not an int. The double factorial n!! recursively multiplies n*(n-2)*... and is only defined on integers, so float inputs (0.1) and other types are rejected with ValueError before recursion starts.
Source
Thrown at maths/double_factorial.py:22
Recursion can be costly for large numbers.
To learn about the theory behind this algorithm:
https://en.wikipedia.org/wiki/Double_factorial
>>> from math import prod
>>> all(double_factorial_recursive(i) == prod(range(i, 0, -2)) for i in range(20))
True
>>> double_factorial_recursive(0.1)
Traceback (most recent call last):
...
ValueError: double_factorial_recursive() only accepts integral values
>>> double_factorial_recursive(-1)
Traceback (most recent call last):
...
ValueError: double_factorial_recursive() not defined for negative values
"""
if not isinstance(n, int):
raise ValueError("double_factorial_recursive() only accepts integral values")
if n < 0:
raise ValueError("double_factorial_recursive() not defined for negative values")
return 1 if n <= 1 else n * double_factorial_recursive(n - 2)
def double_factorial_iterative(num: int) -> int:
"""
Compute double factorial using iterative method.
To learn about the theory behind this algorithm:
https://en.wikipedia.org/wiki/Double_factorial
>>> from math import prod
>>> all(double_factorial_iterative(i) == prod(range(i, 0, -2)) for i in range(20))
True
>>> double_factorial_iterative(0.1)
Traceback (most recent call last):
...View on GitHub (pinned to f5988cc097)
Solutions
- Convert whole floats first: double_factorial_recursive(int(n)) after checking n == int(n).
- Use math.prod(range(n, 0, -2)) yourself if you need leniency for numpy integer types.
- Keep the input in int form end-to-end (avoid float round-trips through JSON or division).
Example fix
# before double_factorial_recursive(9.0) # ValueError # after n = 9.0 assert n == int(n) double_factorial_recursive(int(n)) # 945
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(n, int) or isinstance(n, bool):
if n != int(n):
raise ValueError('n must be integral')
n = int(n) Type guard
def is_integral(n) -> bool:
return isinstance(n, int) or (isinstance(n, float) and n == int(n)) Try / catch
try:
r = double_factorial_recursive(n)
except ValueError as e:
if 'integral values' in str(e):
r = double_factorial_recursive(int(n))
else:
raise Prevention
- Use // instead of / when computing arguments for factorial-family functions.
- Remember bool passes isinstance(n, int); exclude it explicitly in guards.
When it happens
Trigger: Calling double_factorial_recursive(0.1), double_factorial_recursive(5.0), or passing a string/None. The guard is not isinstance(n, int).
Common situations: Whole-valued floats arriving from division or numpy operations; values read from JSON/config as floats; forgetting that bool is an int subclass (True returns 1 silently).
Related errors
- double_factorial_recursive() not defined for negative values
- double_factorial_iterative() only accepts integral values
- double_factorial_iterative() not defined for negative values
- factorial() only accepts integral values
- factorial() not defined for negative values
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/34218757f6e9d382.
Report an issue: GitHub.