我正在尝试检查一个数字是否是一个完美的正方形。但是,我正在处理非常大的数字,因此python因某种原因认为它的无穷大。在代码返回“Inf”之前它会达到1.1 X 10 ^ 154。反正有没有绕过这个?这是代码,lst变量只包含一堆非常非常大的数字
import math
from decimal import Decimal
def main():
for i in lst:
root = math.sqrt(Decimal(i))
print(root)
if int(root + 0.5) ** 2 == i:
print(str(i) + " True")
答案 0 :(得分:3)
将math.sqrt(Decimal(i))
替换为Decimal(i).sqrt()
,以防止Decimal
拒绝float
答案 1 :(得分:2)
我认为您需要查看BigFloat模块,例如:
import bigfloat as bf
b = bf.BigFloat('1e1000', bf.precision(21))
print bf.sqrt(b)
打印BigFloat.exact('9.9999993810013282e+499', precision=53)
答案 2 :(得分:1)
math.sqrt()将参数转换为Python float,其最大值大约为10 ^ 308。
您应该考虑使用gmpy2库。 gmpy2提供非常快速的多精度算术。
如果要检查任意功率,如果数字是完美的幂,则函数gmpy2.is_power()
将返回True
。它可能是立方体或五次幂,因此您需要检查您感兴趣的功率。
>>> gmpy2.is_power(456789**372)
True
您可以使用gmpy2.isqrt_rem()
检查它是否是精确的方格。
>>> gmpy2.isqrt_rem(9)
(mpz(3), mpz(0))
>>> gmpy2.isqrt_rem(10)
(mpz(3), mpz(1))
您可以使用gmpy2.iroot_rem()
检查任意权力。
>>> gmpy2.iroot_rem(13**7 + 1, 7)
(mpz(13), mpz(1))
答案 3 :(得分:1)
@casevh有正确的答案 - 使用一个可以对任意大整数进行数学运算的库。因为你正在寻找正方形,你可能正在使用整数,并且可以说使用浮点类型(包括decimal.Decimal)在某种意义上是不优雅的。
你绝对不应该使用Python的float类型;它的精度有限(大约16位小数)。如果你使用decimal.Decimal,请注意指定精度(这取决于你的数字有多大)。
由于Python有一个大的整数类型,人们可以编写一个相当简单的算法来检查矩形;看看我对这种算法的实现,以及浮点问题的说明,以及如何在下面使用decimal.Decimal。
import math
import decimal
def makendigit(n):
"""Return an arbitraryish n-digit number"""
return sum((j%9+1)*10**i for i,j in enumerate(range(n)))
x=makendigit(30)
# it looks like float will work...
print 'math.sqrt(x*x) - x: %.17g' % (math.sqrt(x*x) - x)
# ...but actually they won't
print 'math.sqrt(x*x+1) - x: %.17g' % (math.sqrt(x*x+1) - x)
# by default Decimal won't be sufficient...
print 'decimal.Decimal(x*x).sqrt() - x:',decimal.Decimal(x*x).sqrt() - x
# ...you need to specify the precision
print 'decimal.Decimal(x*x).sqrt(decimal.Context(prec=30)) - x:',decimal.Decimal(x*x).sqrt(decimal.Context(prec=100)) - x
def issquare_decimal(y,prec=1000):
x=decimal.Decimal(y).sqrt(decimal.Context(prec=prec))
return x==x.to_integral_value()
print 'issquare_decimal(x*x):',issquare_decimal(x*x)
print 'issquare_decimal(x*x+1):',issquare_decimal(x*x+1)
# you can check for "squareness" without going to floating point.
# one option is a bisection search; this Newton's method approach
# should be faster.
# For "industrial use" you should use gmpy2 or some similar "big
# integer" library.
def isqrt(y):
"""Find largest integer <= sqrt(y)"""
if not isinstance(y,(int,long)):
raise ValueError('arg must be an integer')
if y<0:
raise ValueError('arg must be positive')
if y in (0,1):
return y
x0=y//2
while True:
# newton's rule
x1= (x0**2+y)//2//x0
# we don't always get converge to x0=x1, e.g., for y=3
if abs(x1-x0)<=1:
# nearly converged; find biggest
# integer satisfying our condition
x=max(x0,x1)
if x**2>y:
while x**2>y:
x-=1
else:
while (x+1)**2<=y:
x+=1
return x
x0=x1
def issquare(y):
"""Return true if non-negative integer y is a perfect square"""
return y==isqrt(y)**2
print 'isqrt(x*x)-x:',isqrt(x*x)-x
print 'issquare(x*x):',issquare(x*x)
print 'issquare(x*x+1):',issquare(x*x+1)