我怎么能检查一个数字是一个完美的广场?

我怎么能检查一个数字是一个完美的广场?

现在,速度不用担心,只是在工作。


依赖任何浮点运算( math.sqrt(x)x**0.5 )的问题是,你不能确定它是否确切(对于足够大的整数x ,它不会是,甚至可能是溢出)。 幸运的是(如果一个人不急,;-)有许多纯整数方法,比如下面的......:

def is_square(apositiveint):
  x = apositiveint // 2
  seen = set([x])
  while x * x != apositiveint:
    x = (x + (apositiveint // x)) // 2
    if x in seen: return False
    seen.add(x)
  return True

for i in range(110, 130):
   print i, is_square(i)

提示:它基于平方根的“巴比伦算法”,参见维基百科。 它适用于任何正数,因此您有足够的内存用于计算以继续完成;-)。

编辑 :让我们看一个例子...

x = 12345678987654321234567 ** 2

for i in range(x, x+2):
   print i, is_square(i)

根据需要(和合理的时间量)打印;-):

152415789666209426002111556165263283035677489 True
152415789666209426002111556165263283035677490 False

请您根据浮点中间结果提出解决方案之前,要确保他们在这个简单的例子正常工作-这并不 (你只需要一些额外的检查的情况下,计算出的平方根是有点过),只是需要一点护理。

然后尝试使用x**7并找到巧妙的方法来解决您将会遇到的问题,

OverflowError: long int too large to convert to float

当然,随着数量的不断增长,你将不得不越来越聪明。

如果我很着急,当然,我会使用gmpy - 但是,然后,我显然有偏见;-)。

>>> import gmpy
>>> gmpy.is_square(x**7)
1
>>> gmpy.is_square(x**7 + 1)
0

是的,我知道,这太容易了,就像作弊一样(我对Python的感觉总体上是这样的;-) - 根本就没有聪明,只有完美的直接性和简单性(并且在gmpy的情况下,速度很快; - )...


使用牛顿的方法快速调入最接近的整数平方根,然后将其平方,看看它是否是你的数字。 见isqrt。


由于在处理浮点计算时(例如这些计算平方根的方法),您永远无法依赖精确比较,因此不太容易出错的实现

import math
def is_square(integer):
    root = math.sqrt(integer)
    if int(root + 0.5) ** 2 == integer: 
        return True
    else:
        return False

想象一下integer9math.sqrt(9)可能是3.0 ,但也可能是2.999993.00001类的东西,所以将结果直接平方并不可靠。 知道int取最低值,首先将float值增加0.5意味着如果我们处于float仍然具有足够精细分辨率以表示数字的范围内,我们将获得我们要查找的值我们在看。

链接地址: http://www.djcxy.com/p/86597.html

上一篇: How could I check if a number is a perfect square?

下一篇: Test if a number is fibonacci