{"record":{"id":"203131415f27f10f","repo":"TheAlgorithms/Python","slug":"num-must-be-an-integer-or-a-half-integer","errorCode":null,"errorMessage":"num must be an integer or a half-integer","messagePattern":"num must be an integer or a half-integer","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"maths/gamma.py","lineNumber":100,"sourceCode":"    >>> gamma_recursive(-4)\n    Traceback (most recent call last):\n        ...\n    ValueError: math domain error\n    >>> gamma_recursive(172)\n    Traceback (most recent call last):\n        ...\n    OverflowError: math range error\n    >>> gamma_recursive(1.1)\n    Traceback (most recent call last):\n        ...\n    NotImplementedError: num must be an integer or a half-integer\n    \"\"\"\n    if num <= 0:\n        raise ValueError(\"math domain error\")\n    if num > 171.5:\n        raise OverflowError(\"math range error\")\n    elif num - int(num) not in (0, 0.5):\n        raise NotImplementedError(\"num must be an integer or a half-integer\")\n    elif num == 0.5:\n        return math.sqrt(math.pi)\n    else:\n        return 1.0 if num == 1 else (num - 1) * gamma_recursive(num - 1)\n\n\nif __name__ == \"__main__\":\n    from doctest import testmod\n\n    testmod()\n    num = 1.0\n    while num:\n        num = float(input(\"Gamma of: \"))\n        print(f\"gamma_iterative({num}) = {gamma_iterative(num)}\")\n        print(f\"gamma_recursive({num}) = {gamma_recursive(num)}\")\n        print(\"\\nEnter 0 to exit...\")\n","sourceCodeStart":82,"sourceCodeEnd":117,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/gamma.py#L82-L117","documentation":"Raised by gamma_recursive in maths/gamma.py when the fractional part of num is neither 0 nor 0.5. The recursion only has base cases for integers and half-integers (num == 0.5 returns sqrt(pi), num == 1 returns 1.0), so any other fractional input cannot terminate correctly and is rejected with NotImplementedError. This is an intentional API limitation, not a bug.","triggerScenarios":"Calling gamma_recursive(1.1), gamma_recursive(2.7), or any value where num - int(num) is not 0 or 0.5. Note the check happens after the num <= 0 and num > 171.5 checks.","commonSituations":"Assuming gamma_recursive has the same domain as math.gamma or gamma_iterative (which accept any positive float); passing computed floating-point values that pick up small fractional residues (e.g. 2.0000000001 after arithmetic); testing with arbitrary decimals.","solutions":["Use gamma_iterative(num) or math.gamma(num) for arbitrary positive floats.","If you expect an integer/half-integer but floats drift in, round to the nearest 0.5 before calling: num = round(num * 2) / 2.","Catch NotImplementedError explicitly to detect unsupported inputs in generic pipelines."],"exampleFix":"// before\nval = gamma_recursive(3.3)  # NotImplementedError\n\n// after\nfrom maths.gamma import gamma_iterative\nval = gamma_iterative(3.3)  # supports any positive float","handlingStrategy":"fallback","validationCode":"num = round(num * 2) / 2  # snap to nearest half-integer if drift expected\nif num <= 0 or num > 171.5:\n    raise ValueError(f\"out of range: {num}\")","typeGuard":"def is_supported_gamma_input(num) -> bool:\n    return 0 < num <= 171.5 and (num - int(num)) in (0, 0.5)","tryCatchPattern":"try:\n    val = gamma_recursive(num)\nexcept NotImplementedError:\n    val = gamma_iterative(num)  # handles arbitrary positive floats","preventionTips":["Do not assume gamma_recursive equals math.gamma in domain","Snap floating-point drift to the nearest 0.5 before calling if exact half-integers are expected"],"tags":["math","gamma","api-limitation","notimplementederror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}