TheAlgorithms/Python · error · TypeError

Undefined for non-integers

Error message

Undefined for non-integers

What it means

Raised by pi() (Chudnovsky algorithm) in maths/chudnovsky_algorithm.py when the precision argument is not an int. The number of significant digits must be a whole number because it is assigned directly to decimal.getcontext().prec and used to compute iteration count ceil(precision / 14); non-integers are rejected up front with TypeError.

Source

Thrown at maths/chudnovsky_algorithm.py:40

    This algorithm correctly calculates around 14 digits of PI per iteration

    >>> pi(10)
    '3.14159265'
    >>> pi(100)
    '3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706'
    >>> pi('hello')
    Traceback (most recent call last):
        ...
    TypeError: Undefined for non-integers
    >>> pi(-1)
    Traceback (most recent call last):
        ...
    ValueError: Undefined for non-natural numbers
    """

    if not isinstance(precision, int):
        raise TypeError("Undefined for non-integers")
    elif precision < 1:
        raise ValueError("Undefined for non-natural numbers")

    getcontext().prec = precision
    num_iterations = ceil(precision / 14)
    constant_term = 426880 * Decimal(10005).sqrt()
    exponential_term = 1
    linear_term = 13591409
    partial_sum = Decimal(linear_term)
    for k in range(1, num_iterations):
        multinomial_term = factorial(6 * k) // (factorial(3 * k) * factorial(k) ** 3)
        linear_term += 545140134
        exponential_term *= -262537412640768000
        partial_sum += Decimal(multinomial_term * linear_term) / exponential_term
    return str(constant_term / partial_sum)[:-1]


if __name__ == "__main__":

View on GitHub (pinned to f5988cc097)

Solutions

  1. Convert the argument to int before calling: pi(int(precision)).
  2. If precision comes from the command line, wrap with int(sys.argv[1]) and handle the conversion error separately.
  3. Ensure numpy floats are cast with int() since np.int64 passes isinstance(x, int) checks only via casting on some platforms.

Example fix

# before
pi('100')   # TypeError: Undefined for non-integers
pi(10.5)    # TypeError

# after
pi(int('100'))
pi(int(10.5))  # or round first if you meant a fractional size
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(precision, int) or isinstance(precision, bool):
    precision = int(precision)  # after your own validation
result = pi(precision)

Type guard

def is_int_precision(p) -> bool:
    return isinstance(p, int) and not isinstance(p, bool)

Try / catch

try:
    digits = pi(precision)
except TypeError:
    digits = pi(int(float(precision)))  # last-resort coercion of numeric strings

Prevention

When it happens

Trigger: Calling pi('hello'), pi(10.5), pi(True is fine but pi(2.0) or any float/str precision triggers it. The guard is not isinstance(precision, int).

Common situations: Precision read from argv or config as a string ('100' instead of 100); precision computed as a float (e.g. n * 1.5 or results of numpy scalars); API boundaries where JSON numbers arrive as floats.

Related errors


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