TheAlgorithms/Python · error · ValueError
factorial() only accepts integral values
Error message
factorial() only accepts integral values
What it means
Raised by factorial() in maths/factorial.py when number != int(number) — i.e. the argument has a fractional part. The iterative loop for i in range(1, number + 1) needs a whole number; unlike isinstance-based guards this one accepts float types as long as the value is integral (5.0 passes, 5.5 raises).
Source
Thrown at maths/factorial.py:29
>>> all(factorial(i) == math.factorial(i) for i in range(20))
True
>>> factorial(0.1)
Traceback (most recent call last):
...
ValueError: factorial() only accepts integral values
>>> factorial(-1)
Traceback (most recent call last):
...
ValueError: factorial() not defined for negative values
>>> factorial(1)
1
>>> factorial(6)
720
>>> factorial(0)
1
"""
if number != int(number):
raise ValueError("factorial() only accepts integral values")
if number < 0:
raise ValueError("factorial() not defined for negative values")
value = 1
for i in range(1, number + 1):
value *= i
return value
def factorial_recursive(n: int) -> int:
"""
Calculate the factorial of a positive integer
https://en.wikipedia.org/wiki/Factorial
>>> import math
>>> all(factorial_recursive(i) == math.factorial(i) for i in range(20))
True
>>> factorial_recursive(0.1)
Traceback (most recent call last):View on GitHub (pinned to f5988cc097)
Solutions
- Round or validate first: use factorial(int(number)) only when number == int(number).
- Prefer math.factorial, which raises a clear TypeError for floats entirely.
- Fix upstream arithmetic to use // or round deliberately rather than truncating silently.
Example fix
# before factorial(7 / 2) # 3.5 -> ValueError # after n = 7 // 2 # or round(7 / 2) if rounding is intended factorial(n)
Defensive patterns
Strategy: validation
Validate before calling
if number != int(number):
raise ValueError(f'factorial needs an integral value, got {number}')
number = int(number) Type guard
def is_integral(n) -> bool:
return n == int(n) Try / catch
try:
r = factorial(number)
except ValueError as e:
if 'integral values' in str(e):
raise ValueError(f'non-integral input {number} from upstream division') from e
raise Prevention
- Use // (floor division) or round() when computing factorial arguments.
- Prefer math.factorial for a stricter, well-documented contract.
When it happens
Trigger: Calling factorial(5.5), factorial(-2.5), or any value whose int() truncation differs from itself. Note factorial(-3.0) passes this check and hits the negative-values ValueError next, and factorial('5') raises TypeError from the comparison, not this message.
Common situations: Floats produced by division (n / 2 for odd n), averaging, or numpy arithmetic; decoded JSON floats with fractional parts; passing a Decimal whose value is non-integral.
Related errors
- double_factorial_recursive() only accepts integral values
- double_factorial_recursive() not defined for negative values
- double_factorial_iterative() only accepts integral values
- double_factorial_iterative() not defined for negative values
- factorial() not defined for negative values
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/577982e214d312af.
Report an issue: GitHub.