Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 完美整数求值失败,输入343_Python_Math - Fatal编程技术网

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()
不会给出期望的结果@保尔科尼利厄斯