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
- Convert the argument to int before calling: pi(int(precision)).
- If precision comes from the command line, wrap with int(sys.argv[1]) and handle the conversion error separately.
- 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
- Convert argv/config values with int() at the boundary.
- Cast numpy scalars and JSON numbers to int before passing precision arguments.
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
- Undefined for non-natural numbers
- Both points must have the same dimension.
- Monogons and Digons are not polygons in the Euclidean space
- All values must be greater than 0
- Sequence only defined for positive integers
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/8aa0300117874e71.
Report an issue: GitHub.