python中的整数平方根

2024-05-01 21:25:28 发布

您现在位置:Python中文网/ 问答频道 /正文

python或标准库中是否存在整数平方根?我希望它是精确的(即返回一个整数),如果没有解,就吠叫。

就在那一刻,我卷起了自己的天真:

def isqrt(n):
    i = int(math.sqrt(n) + 0.5)
    if i**2 == n:
        return i
    raise ValueError('input was not a perfect square')

但它很难看,我不太相信大整数。我可以在正方形中迭代,如果超过这个值就放弃,但我认为这样做有点慢。我想我可能会重新发明轮子,这样的东西肯定已经存在于python中了。。。


Tags: input标准returnifdefnot整数math
3条回答

牛顿的方法对整数非常有效:

def isqrt(n):
    x = n
    y = (x + 1) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

这将返回最大整数x,其中x*x不超过n。如果要检查结果是否正是平方根,只需执行乘法检查n是否是完美的平方。

我在my blog讨论这个算法,以及另外三个计算平方根的算法。

在标准库中更新:Python 3.8 has a ^{} function

我在小(0…222)和大(250001)输入上对每个(正确的)函数进行了基准测试。在这两种情况下,明显的赢家都是排名第一的^{} suggested by mathmandan,其次是Python 3.8的^{},第三是ActiveState recipe linked by NPE。ActiveState配方有一系列的分区,可以用移位来代替,这使它更快一些(但仍然落后于本机函数):

def isqrt(n):
    if n > 0:
        x = 1 << (n.bit_length() + 1 >> 1)
        while True:
            y = (x + n // x) >> 1
            if y >= x:
                return x
            x = y
    elif n == 0:
        return 0
    else:
        raise ValueError("square root not defined for negative numbers")

基准结果:

(*由于gmpy2.isqrt返回一个gmpy2.mpz对象,该对象的行为主要与int相似,因此可能需要将其转换回int以供某些使用。)

很抱歉,回复太晚了,我刚刚无意中看到这一页。如果将来有人访问这个页面,python模块gmpy2被设计成可以处理非常大的输入,其中包括一个整数平方根函数。

示例:

>>> import gmpy2
>>> gmpy2.isqrt((10**100+1)**2)
mpz(10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001L)
>>> gmpy2.isqrt((10**100+1)**2 - 1)
mpz(10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000L)

当然,所有东西都有“mpz”标签,但mpz与int兼容:

>>> gmpy2.mpz(3)*4
mpz(12)

>>> int(gmpy2.mpz(12))
12

请参阅my other answer以了解有关此方法相对于此问题的其他一些答案的性能的讨论。

下载:https://code.google.com/p/gmpy/

相关问题 更多 >