{"record":{"id":"9def63240f29910a","repo":"TheAlgorithms/Python","slug":"num-must-be-non-negative-integer","errorCode":null,"errorMessage":"num must be non-negative integer","messagePattern":"num must be non-negative integer","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"maths/integer_square_root.py","lineNumber":48,"sourceCode":"    46340\n    >>> from math import isqrt\n    >>> all(integer_square_root(i) == isqrt(i) for i in range(20))\n    True\n    >>> integer_square_root(-1)\n    Traceback (most recent call last):\n        ...\n    ValueError: num must be non-negative integer\n    >>> integer_square_root(1.5)\n    Traceback (most recent call last):\n        ...\n    ValueError: num must be non-negative integer\n    >>> integer_square_root(\"0\")\n    Traceback (most recent call last):\n        ...\n    ValueError: num must be non-negative integer\n    \"\"\"\n    if not isinstance(num, int) or num < 0:\n        raise ValueError(\"num must be non-negative integer\")\n\n    if num < 2:\n        return num\n\n    left_bound = 0\n    right_bound = num // 2\n\n    while left_bound <= right_bound:\n        mid = left_bound + (right_bound - left_bound) // 2\n        mid_squared = mid * mid\n        if mid_squared == num:\n            return mid\n\n        if mid_squared < num:\n            left_bound = mid + 1\n        else:\n            right_bound = mid - 1\n","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/maths/integer_square_root.py#L30-L66","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nroot = integer_square_root(x)  # x is 16.0 after float math\n\n// after\nroot = integer_square_root(int(round(x)))  # or math.isqrt(int(x))","handlingStrategy":"validation","validationCode":"if isinstance(num, float):\n    if not num.is_integer():\n        raise ValueError(f\"not a whole number: {num}\")\n    num = int(num)\nif num < 0:\n    num = 0  # only if mathematically safe to clamp\nroot = integer_square_root(num)","typeGuard":"def is_nonneg_int(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool) and v >= 0","tryCatchPattern":"try:\n    r = integer_square_root(x)\nexcept ValueError:\n    r = math.isqrt(max(0, int(x)))","preventionTips":["Cast whole floats to int before calling","Consider math.isqrt from the standard library as the primary choice"],"tags":["math","square-root","binary-search","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}