{"record":{"id":"577982e214d312af","repo":"TheAlgorithms/Python","slug":"factorial-only-accepts-integral-values","errorCode":null,"errorMessage":"factorial() only accepts integral values","messagePattern":"factorial\\(\\) only accepts integral values","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"maths/factorial.py","lineNumber":29,"sourceCode":"    >>> all(factorial(i) == math.factorial(i) for i in range(20))\n    True\n    >>> factorial(0.1)\n    Traceback (most recent call last):\n        ...\n    ValueError: factorial() only accepts integral values\n    >>> factorial(-1)\n    Traceback (most recent call last):\n        ...\n    ValueError: factorial() not defined for negative values\n    >>> factorial(1)\n    1\n    >>> factorial(6)\n    720\n    >>> factorial(0)\n    1\n    \"\"\"\n    if number != int(number):\n        raise ValueError(\"factorial() only accepts integral values\")\n    if number < 0:\n        raise ValueError(\"factorial() not defined for negative values\")\n    value = 1\n    for i in range(1, number + 1):\n        value *= i\n    return value\n\n\ndef factorial_recursive(n: int) -> int:\n    \"\"\"\n    Calculate the factorial of a positive integer\n    https://en.wikipedia.org/wiki/Factorial\n\n    >>> import math\n    >>> all(factorial_recursive(i) == math.factorial(i) for i in range(20))\n    True\n    >>> factorial_recursive(0.1)\n    Traceback (most recent call last):","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/factorial.py#L11-L47","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nfactorial(7 / 2)  # 3.5 -> ValueError\n\n# after\nn = 7 // 2  # or round(7 / 2) if rounding is intended\nfactorial(n)","handlingStrategy":"validation","validationCode":"if number != int(number):\n    raise ValueError(f'factorial needs an integral value, got {number}')\nnumber = int(number)","typeGuard":"def is_integral(n) -> bool:\n    return n == int(n)","tryCatchPattern":"try:\n    r = factorial(number)\nexcept ValueError as e:\n    if 'integral values' in str(e):\n        raise ValueError(f'non-integral input {number} from upstream division') from e\n    raise","preventionTips":["Use // (floor division) or round() when computing factorial arguments.","Prefer math.factorial for a stricter, well-documented contract."],"tags":["maths","factorial","validation","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}