I would like to understand why something is happening. I needed to implement the integer square root in Python (isqrt(64) = 8 = isqrt(80)). I was convinced that the naive approach:
def isqrt(n):
return int(math.sqrt(n))
was bound to fail occasionally when the n passed is a square number, assuming that Python converts to floats, then performs a square root calculation on floats. For instance, calling isqrt(13*13) I expected that after converting to floats and calculating sqrt, you could get something like 12.999999843, which after casting to integer would give us 12.
But I performed large loops testing values, big and small, and always get the correct result. It would seem there is no need to implement a special square root for integers, after all!
Not understanding bothers me, as much as when something that was supposed to work is failing. Why is this happening?
There is another question regarding integer square root in python: Integer square root in python
In the isqrt() defined there, a +0.5 is added to n, which I guess was included precisely to fight the issue I mentioned I was expecting, but cannot find in a specific case.
EDIT: Forgot to specify, I am using Python 2.7
math.sqrt(5) == 2.23606797749979
, sosqrt
results are always floating point even for small integer arguments. But I think that changed in Python 3. Python is dynamically typed, so can in principle change the type of the result as needed - giving an integer result (including large integers) where the argument is integer if that's what the powers that be decided. It makes a lot of sense, but I haven't checked (hence comment not answer). – Scagliolamath.sqrt()
is directly forwarded (complex number handling magic aside) to the corresponding function inlibm
(note thatDecimal.sqrt()
is different). Not surprisingly, a pure C version has the same behaviour – Disposal