@casevh有正確的答案 - 使用可以對任意大的整型做數學庫。既然你正在尋找正方形,你可能正在用整數工作,並且有人可能會爭辯說使用浮點類型(包括decimal.Decimal)在某種意義上是不雅觀的。
你肯定不應該使用Python的浮點類型;它的精度有限(約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)
不增加精度,它不測試它是否是一個完美的正方形。 – casevh
爲什麼使用這個模塊而不是使用'Decimal'? – delnan