TheAlgorithms/Python · error · ValueError
num must be non-negative integer
Error message
num must be non-negative integer
What it means
Raised by integer_square_root in maths/integer_square_root.py when num is not an int or is negative. The function computes floor(sqrt(num)) via binary search, which is only defined for non-negative integers; a single guard rejects floats (even whole-valued ones like 2.0), strings, and negatives with ValueError. Use math.isqrt for an equivalent standard-library implementation.
Source
Thrown at maths/integer_square_root.py:48
46340
>>> from math import isqrt
>>> all(integer_square_root(i) == isqrt(i) for i in range(20))
True
>>> integer_square_root(-1)
Traceback (most recent call last):
...
ValueError: num must be non-negative integer
>>> integer_square_root(1.5)
Traceback (most recent call last):
...
ValueError: num must be non-negative integer
>>> integer_square_root("0")
Traceback (most recent call last):
...
ValueError: num must be non-negative integer
"""
if not isinstance(num, int) or num < 0:
raise ValueError("num must be non-negative integer")
if num < 2:
return num
left_bound = 0
right_bound = num // 2
while left_bound <= right_bound:
mid = left_bound + (right_bound - left_bound) // 2
mid_squared = mid * mid
if mid_squared == num:
return mid
if mid_squared < num:
left_bound = mid + 1
else:
right_bound = mid - 1
View on GitHub (pinned to f5988cc097)
Solutions
- Convert whole floats: call integer_square_root(int(num)) when num.is_integer().
- Clamp tiny negative round-off to 0: num = max(0, num) when the value is mathematically non-negative.
- Prefer the standard library's math.isqrt, which has the same int-only requirement but is faster and battle-tested.
Example fix
// before root = integer_square_root(x) # x is 16.0 after float math // after root = integer_square_root(int(round(x))) # or math.isqrt(int(x))
Defensive patterns
Strategy: validation
Validate before calling
if isinstance(num, float):
if not num.is_integer():
raise ValueError(f"not a whole number: {num}")
num = int(num)
if num < 0:
num = 0 # only if mathematically safe to clamp
root = integer_square_root(num) Type guard
def is_nonneg_int(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) and v >= 0 Try / catch
try:
r = integer_square_root(x)
except ValueError:
r = math.isqrt(max(0, int(x))) Prevention
- Cast whole floats to int before calling
- Consider math.isqrt from the standard library as the primary choice
When it happens
Trigger: Calling integer_square_root(-1), integer_square_root(1.5), integer_square_root(2.0), or integer_square_root('0'). The guard 'if not isinstance(num, int) or num < 0' catches all of these; note 0 and 1 are fine (num < 2 returns num).
Common situations: Passing floats from division or numpy computations where a whole float (16.0) was expected to be accepted; string input from parsing; negative values arising from floating-point round-off on what should be non-negative computed quantities.
Related errors
- mod inverse of {a!r} and {m!r} does not exist
- factorial() not defined for negative values
- surface_area_cube() only accepts non-negative values
- surface_area_cuboid() only accepts non-negative values
- surface_area_sphere() only accepts non-negative values
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/9def63240f29910a.
Report an issue: GitHub.