我想了解为什么会发生一些事情。我需要在Python中实现整数平方根(isqrt(64)= 8 = isqrt(80))。我确信天真的方法:
def isqrt(n):
return int(math.sqrt(n))
当传递的n是一个平方数时,偶尔会失败,假设Python转换为浮点数,然后对浮点数执行平方根计算。例如,调用isqrt(13 * 13)我希望在转换为浮点数并计算sqrt之后,你可以获得类似12.999999843的东西,在转换为整数后会给出12。
但是我执行了大型循环测试值,无论大小,总是得到正确的结果。毕竟,似乎没有必要为整数实现特殊的平方根!
不理解困扰我,就像当应该工作的东西失败一样。为什么会这样?
在python中有关于整数平方根的另一个问题:Integer square root in python
在那里定义的isqrt()中,将一个+0.5添加到n中,我猜这是为了解决我提到的我期待的问题,但是在特定情况下无法找到。
编辑:忘了指定,我使用的是Python 2.7
答案 0 :(得分:3)
在C类型long
作为64位整数且C类型double
实现为64位IEEE浮点数的机器上使用python 2.7产生
>>> import math
>>> x = (2<<53) + 1
>>> int(math.sqrt(x*x)) == x
False
我作弊并选择了64位IEEE浮点数无法准确表示的数字(但是python的整数类型可以),(2<<53) + 1
。 Python 2.7将x*x
计算为python 2.7 long
整数。 (注意:这与C long
不同; python 2.7可以将2<<600
表示为整数,但C不能。)
说到2<<600
,
>>> import math
>>> x = 2<<600
>>> int(math.sqrt(x*x)) == x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float