{"record":{"id":"df2a1c717a816bef","repo":"TheAlgorithms/Python","slug":"math-domain-error","errorCode":null,"errorMessage":"math domain error","messagePattern":"math domain error","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"maths/gamma.py","lineNumber":45,"sourceCode":"    >>> gamma_iterative(0)\n    Traceback (most recent call last):\n        ...\n    ValueError: math domain error\n    >>> gamma_iterative(9)\n    40320.0\n    >>> from math import gamma as math_gamma\n    >>> all(.99999999 < gamma_iterative(i) / math_gamma(i) <= 1.000000001\n    ...     for i in range(1, 50))\n    True\n    >>> gamma_iterative(-1)/math_gamma(-1) <= 1.000000001\n    Traceback (most recent call last):\n        ...\n    ValueError: math domain error\n    >>> gamma_iterative(3.3) - math_gamma(3.3) <= 0.00000001\n    True\n    \"\"\"\n    if num <= 0:\n        raise ValueError(\"math domain error\")\n\n    return quad(integrand, 0, inf, args=(num))[0]\n\n\ndef integrand(x: float, z: float) -> float:\n    return math.pow(x, z - 1) * math.exp(-x)\n\n\ndef gamma_recursive(num: float) -> float:\n    \"\"\"\n    Calculates the value of Gamma function of num\n    where num is either an integer (1, 2, 3..) or a half-integer (0.5, 1.5, 2.5 ...).\n    Implemented using recursion\n    Examples:\n    >>> from math import isclose, gamma as math_gamma\n    >>> gamma_recursive(0.5)\n    1.7724538509055159\n    >>> gamma_recursive(1)","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/gamma.py#L27-L63","documentation":"Raised by gamma_iterative in maths/gamma.py when num <= 0. The function approximates the Gamma function via numerical integration of exp(-x)*x^(z-1) from 0 to infinity, which diverges for non-positive z, so the code explicitly mirrors CPython's math.gamma by raising ValueError('math domain error'). This is a precondition check at the top of the function, before scipy's quad is called.","triggerScenarios":"Calling gamma_iterative with num = 0 or any negative value, e.g. gamma_iterative(-1) or gamma_iterative(0). Any num <= 0 hits the 'if num <= 0' branch and raises immediately.","commonSituations":"Porting code from math.gamma and assuming different domain rules; passing user-supplied or computed values (e.g. shifted by a subtraction) that can reach 0 or below; looping over ranges that include 0 without filtering.","solutions":["Only call gamma_iterative with strictly positive arguments (num > 0).","If negative or zero inputs are legitimate in your domain, switch to a library that supports Gamma's analytic continuation or reflection formula (e.g. scipy.special.gamma handles negatives at non-integers; use math.gamma only for num > 0).","Guard call sites: validate num > 0 before calling and branch to your own handling otherwise."],"exampleFix":"// before\nval = gamma_iterative(x)  # x may be <= 0\n\n// after\nif x <= 0:\n    raise ValueError(f\"gamma_iterative requires num > 0, got {x}\")\nval = gamma_iterative(x)","handlingStrategy":"validation","validationCode":"def safe_gamma_iterative(num: float) -> float:\n    if num <= 0:\n        raise ValueError(f\"gamma defined only for num > 0, got {num}\")\n    return gamma_iterative(num)","typeGuard":"def is_positive_real(num) -> bool:\n    return isinstance(num, (int, float)) and num > 0","tryCatchPattern":"try:\n    val = gamma_iterative(x)\nexcept ValueError as e:\n    if 'domain' in str(e):\n        # handle non-positive input\n        ...\n    raise","preventionTips":["Treat num > 0 as a hard precondition wherever gamma_iterative is used","Filter zeros and negatives out of input arrays before batch processing"],"tags":["math","gamma","validation","valueerror"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}