TheAlgorithms/Python · error · ValueError

factorial_recursive() not defined for negative values

Error message

factorial_recursive() not defined for negative values

What it means

Raised by factorial_recursive() in maths/factorial.py when the argument n is a negative int. Factorial is undefined for negative integers, so the function rejects n < 0 with ValueError before recursing; without the guard the recursion would never terminate (n - 1 moves away from the base cases 0 and 1).

Source

Thrown at maths/factorial.py:58

    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):
        ...
    ValueError: factorial_recursive() only accepts integral values
    >>> factorial_recursive(-1)
    Traceback (most recent call last):
        ...
    ValueError: factorial_recursive() not defined for negative values
    """
    if not isinstance(n, int):
        raise ValueError("factorial_recursive() only accepts integral values")
    if n < 0:
        raise ValueError("factorial_recursive() not defined for negative values")
    return 1 if n in {0, 1} else n * factorial_recursive(n - 1)


if __name__ == "__main__":
    import doctest

    doctest.testmod()

    n = int(input("Enter a positive integer: ").strip() or 0)
    print(f"factorial{n} is {factorial(n)}")

View on GitHub (pinned to f5988cc097)

Solutions

  1. Check n >= 0 before calling and clamp or reject the input at your own boundary.
  2. Fix the upstream computation that produced the negative value (usually an off-by-one or a reversed subtraction).
  3. If your domain genuinely needs negative-integer factorials, use a Gamma-function library (e.g. scipy.special.gamma), noting poles at negative integers.

Example fix

# before
n = len(items) - k  # can be negative when k > len(items)
factorial_recursive(n)

# after
n = len(items) - k
if n < 0:
    raise ValueError(f'k={k} exceeds len(items)={len(items)}')
factorial_recursive(n)
Defensive patterns

Strategy: validation

Validate before calling

if n < 0:
    raise ValueError(f'factorial undefined for negative n={n}')
result = factorial_recursive(n)

Type guard

def is_valid_factorial_arg(n: object) -> bool:
    return isinstance(n, int) and n >= 0

Try / catch

try:
    factorial_recursive(n)
except ValueError as exc:
    if 'negative' in str(exc):
        n = 0  # clamp only if semantically acceptable
    else:
        raise

Prevention

When it happens

Trigger: Calling factorial_recursive(-1), factorial_recursive(-10), or any negative int. The isinstance check passes, then `if n < 0` raises immediately.

Common situations: Off-by-one bugs producing negative loop bounds, subtracting user-supplied values that go below zero, unvalidated command-line arguments, or sign errors in combinatorics formulas.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/f17f3e1da72441e6. Report an issue: GitHub.