Python 完美整数求值失败,输入343
完美幂是一个正整数,可以表示为另一个正整数的整数幂 任务是检查给定的整数是否为完美幂 这是我的密码:Python 完美整数求值失败,输入343,python,math,Python,Math,完美幂是一个正整数,可以表示为另一个正整数的整数幂 任务是检查给定的整数是否为完美幂 这是我的密码: 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]
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
(73)。因为343**(1.0/float(3))
不是7.0
,而是6.99999999999999
。您试图用浮点数学解决一个整数问题。因为343**(1.0/float(3))
不是7.0
,而是6.9999999999999
。您试图用浮点数学来解决一个整数问题。如本文所述,浮点数字在计算机中的存储并不完美。基于浮点计算中存在的这个非常小的差异,您很可能在计算中遇到一些错误
当我运行你的函数时,等式((x**(1./float(z)))*10%10)
导致9.999999999986
,不像预期的那样。这是由于浮点运算中的微小错误造成的
如果必须将该值计算为浮点值(这在总体目标中可能有用,也可能不有用),则可以为结果定义精度范围。简单的检查如下所示:
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)
精度=1.e-6
检查=(x**(1/浮动(z))*10%10
如果检查==0:
#对以前的代码没有更改
elif 10-检查<精度:
c、 附加(int(x**(1./float(z)))+1)
c、 附加(z)
精度
是用科学记数法定义的,等于1 x 10^(-6)
或0.000001
,但如果这一大范围的精度引入其他误差,其幅度可能会降低,这是不可能的,但完全可能的。我在结果中添加了1
,因为原始数字小于目标数字。如本文所述,浮点数字在计算机中的存储并不完美。基于浮点计算中存在的这个非常小的差异,您很可能在计算中遇到一些错误
当我运行你的函数时,等式((x**(1./float(z)))*10%10)
导致9.999999999986
,不像预期的那样。这是由于浮点运算中的微小错误造成的
如果必须将该值计算为浮点值(这在总体目标中可能有用,也可能不有用),则可以为结果定义精度范围。简单的检查如下所示:
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)
精度=1.e-6
检查=(x**(1/浮动(z))*10%10
如果检查==0:
#对以前的代码没有更改
elif 10-检查<精度:
c、 附加(int(x**(1./float(z)))+1)
c、 附加(z)
精度
是用科学记数法定义的,等于1 x 10^(-6)
或0.000001
,但如果这一大范围的精度引入其他误差,其幅度可能会降低,这是不可能的,但完全可能的。我在结果中添加了1
,因为原始数字小于目标值。由于其他答案已经解释了算法失败的原因,我将集中精力提供一种避免该问题的替代算法
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)
与您的算法一样,如果有多个解决方案,则只返回第一个解决方案。由于其他答案已经解释了您的算法失败的原因,我将集中精力提供一种替代算法,以避免该问题
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)
与您的算法一样,如果有多个解决方案,这只会返回第一个解决方案。当提出问题时,请尝试始终以一种对尽可能多的其他人有用的方式提问(有类似问题)。例如,标题“完美整数评估因输入343而失败”更有意义。此外,请更准确地描述由此产生的问题,而不是“不起作用”。它会崩溃吗?导致错误的结果?还是别的?谢谢你的建议。对不起,我是新来的。当我问一个问题时,请尽量用一种对尽可能多的人有用的方式来问(有类似问题的)。例如,标题“完美整数评估因输入343而失败”更有意义。此外,请更准确地描述由此产生的问题,而不是“不起作用”。它会崩溃吗?导致错误的结果?还是别的?谢谢你的建议。对不起,我是新来的,但是(8**(1./3.)-是2。为什么343变为.99999?因为计算机表示浮点数的方式以及标准数学函数固有的舍入误差。请参阅以了解比您想知道的更多的详细信息。但是(8**(1./3.)-是2。为什么343变为.99999?因为计算机表示浮点数的方式以及标准数学函数固有的舍入误差。请参阅,以了解比您想知道的更多的详细信息。谢谢。我只是试着用数学的方法来解决这个问题。请看这个:答案很好,但也许最好使用标准库函数round()将浮点结果强制为最接近的整数。我是Python的NoOB,但是我在C++中做了很多科学计算。我不知道库和助手,但我可以手动做一些有意义的事情。也许
round()
不会给出期望的结果@PaulCorneliust谢谢你。我只是试着用数学的方法来解决这个问题。请看这个:答案很好,但也许最好使用标准库函数round()将浮点结果强制为最接近的整数。我是Python的NoOB,但是我在C++中做了很多科学计算。我不知道库和助手,但我可以手动做一些有意义的事情。也许round()
不会给出期望的结果@保尔科尼利厄斯