完美功率是一个正整数,可以表示为另一个正整数的整数幂。
任务是检查给定的整数是否是完美的幂。
这是我的代码:
def isPP2(x):
c=[]
for z in range(2,int(x/2)+1):
if (x**(1./float(z)))*10%10==0:
c.append(int(x**(1./float(z)))), c.append(z)
if len(c)>=2:
return c[0:2]
else:
return None
它适用于所有数字,例如:
isPP2(81)
[9, 2]
isPP2(2187)
[3, 7]
但它不适用343
(7 3 )。
答案 0 :(得分:4)
由于343**(1.0/float(3))
不是7.0
,因此6.99999999999999
。您正在尝试使用浮点数学来解决整数问题。
答案 1 :(得分:0)
如此link中所述,浮点数不能完美地存储在计算机中。基于浮点计算中持续存在的这种非常小的差异,您很可能在计算中遇到一些错误。
当我运行您的函数时,等式((x ** (1./float(z))) * 10 % 10)
会产生9.99999999999999986
,不 10
。这是由于浮点运算中涉及的轻微错误。
如果您必须将值计算为浮点数(可能在您的总体目标中有用或可能没用),您可以为结果定义精度范围。简单的检查看起来像这样:
precision = 1.e-6
check = (x ** (1./float(z))) * 10 % 10
if check == 0:
# No changes to previous code
elif 10 - check < precision:
c.append(int(x**(1./float(z))) + 1)
c.append(z)
precision
以科学计数法定义,等于1 x 10^(-6)
或0.000001
,但如果这种大范围的精度引入其他错误,则可能会减小幅度,这种情况不太可能但完全有可能。我将1
添加到结果中,因为原始数字小于目标。
答案 2 :(得分:0)
由于其他答案已经解释为什么您的算法失败,我将集中精力提供一种避免此问题的替代算法。
import math
def isPP2(x):
# exp2 = log_2(x) i.e. 2**exp2 == x
# is a much better upper bound for the exponents to test,
# as 2 is the smallest base exp2 is the biggest exponent we can expect.
exp2 = math.log(x, 2)
for exp in range(2, int(exp2)):
# to avoid floating point issues we simply round the base we get
# and then test it against x by calculating base**exp
# side note:
# according to the docs ** and the build in pow()
# work integer based as long as all arguments are integer.
base = round( x**(1./float(exp)) )
if base**exp == x:
return base, exp
return None
print( isPP2(81) ) # (9, 2)
print( isPP2(2187) ) # (3, 7)
print( isPP2(343) ) # (7, 3)
print( isPP2(232**34) ) # (53824, 17)
与算法一样,如果有多个算法,则只返回第一个解决方案。