{"record":{"id":"34218757f6e9d382","repo":"TheAlgorithms/Python","slug":"double-factorial-recursive-only-accepts-integral","errorCode":null,"errorMessage":"double_factorial_recursive() only accepts integral values","messagePattern":"double_factorial_recursive\\(\\) only accepts integral values","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"maths/double_factorial.py","lineNumber":22,"sourceCode":"    Recursion can be costly for large numbers.\n\n    To learn about the theory behind this algorithm:\n    https://en.wikipedia.org/wiki/Double_factorial\n\n    >>> from math import prod\n    >>> all(double_factorial_recursive(i) == prod(range(i, 0, -2)) for i in range(20))\n    True\n    >>> double_factorial_recursive(0.1)\n    Traceback (most recent call last):\n        ...\n    ValueError: double_factorial_recursive() only accepts integral values\n    >>> double_factorial_recursive(-1)\n    Traceback (most recent call last):\n        ...\n    ValueError: double_factorial_recursive() not defined for negative values\n    \"\"\"\n    if not isinstance(n, int):\n        raise ValueError(\"double_factorial_recursive() only accepts integral values\")\n    if n < 0:\n        raise ValueError(\"double_factorial_recursive() not defined for negative values\")\n    return 1 if n <= 1 else n * double_factorial_recursive(n - 2)\n\n\ndef double_factorial_iterative(num: int) -> int:\n    \"\"\"\n    Compute double factorial using iterative method.\n\n    To learn about the theory behind this algorithm:\n    https://en.wikipedia.org/wiki/Double_factorial\n\n    >>> from math import prod\n    >>> all(double_factorial_iterative(i) == prod(range(i, 0, -2)) for i in range(20))\n    True\n    >>> double_factorial_iterative(0.1)\n    Traceback (most recent call last):\n        ...","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/double_factorial.py#L4-L40","documentation":"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.","triggerScenarios":"Calling double_factorial_recursive(0.1), double_factorial_recursive(5.0), or passing a string/None. The guard is not isinstance(n, int).","commonSituations":"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).","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)."],"exampleFix":"# before\ndouble_factorial_recursive(9.0)  # ValueError\n\n# after\nn = 9.0\nassert n == int(n)\ndouble_factorial_recursive(int(n))  # 945","handlingStrategy":"type-guard","validationCode":"if not isinstance(n, int) or isinstance(n, bool):\n    if n != int(n):\n        raise ValueError('n must be integral')\n    n = int(n)","typeGuard":"def is_integral(n) -> bool:\n    return isinstance(n, int) or (isinstance(n, float) and n == int(n))","tryCatchPattern":"try:\n    r = double_factorial_recursive(n)\nexcept ValueError as e:\n    if 'integral values' in str(e):\n        r = double_factorial_recursive(int(n))\n    else:\n        raise","preventionTips":["Use // instead of / when computing arguments for factorial-family functions.","Remember bool passes isinstance(n, int); exclude it explicitly in guards."],"tags":["maths","factorial","recursion","validation","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}