Python中整数平方根的精确性

时间:2016-01-21 08:15:47

标签: python python-2.7 integer math.sqrt

我想了解为什么会发生一些事情。我需要在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

1 个答案:

答案 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