基于this answer,我在 Python 3.x 中实现了一个简单的算法,以确定整数n
是否是另一个整数的幂{{1} 1}}。但是,该算法不会返回正确的结果。链接答案中的代码是:
base
(A comment表示从逻辑上检查while (n % 3 == 0) {
n /= 3;
}
return n == 1;
也是必要的。这是我的代码:
n == 0
我编写了简单的测试代码来测试某些范围的基数和指数,但它返回的结果是不正确的。测试代码:
def is_power(n: int, base: int) -> bool:
if n == 0:
return false
while (n % base == 0):
n /= base
return n == 1
我用更大的范围测试了它,但是为了输出,我在这个例子中限制了它。这输出:
for base in range(3, 10):
print("Base: {0}".format(base))
for exp in range(30, 40):
b = is_power(pow(base, exp), base)
if not(b):
print("{: <3}: {: <5}".format(exp, str(b)))
这显然是不正确的。我尝试调试一个小例子,其中Base: 3
35 : False
36 : False
37 : False
38 : False
39 : False
Base: 4
Base: 5
30 : False
31 : False
32 : False
33 : False
34 : False
35 : False
36 : False
37 : False
38 : False
39 : False
Base: 6
35 : False
36 : False
37 : False
38 : False
39 : False
Base: 7
30 : False
31 : False
32 : False
33 : False
34 : False
35 : False
36 : False
37 : False
38 : False
39 : False
Base: 8
Base: 9
30 : False
31 : False
32 : False
33 : False
34 : False
35 : False
36 : False
37 : False
38 : False
39 : False
和n = pow(3, 35)
在循环中产生base = 3
的这些值:
n
并且循环结束,因为50031545098999707/3 == 1.667718169966656 9 e + 16(注意最后一位数字不同)。这是问题吗? Python的计算失败了吗?如果没有,这个算法有什么问题?
如果我使用50031545098999707
1.6677181699666568e+16
代码,算法也会失败,但我不一定会对此感到惊讶,因为查看一个示例表明math.pow
和pow
并非总是如此返回相同的值。
math.pow
答案 0 :(得分:7)
由于您使用的是Python 3,因此您应该使用
def is_power(n: int, base: int) -> bool:
if n == 0:
return false
while (n % base == 0):
n //= base
# ^^ note two slashes
return n == 1
在Python 3.x中,/
操作始终执行&#34;实际划分&#34;并返回一个浮点数,但在你链接的算法中,它期望/
进行整数除法,这是用//
完成的( &#34;楼层划分&#34;)运营商。
测试失败真的是因为浮点运算缺乏精度,正如您所料。当/
返回无限精度实数时,该算法仍然正确。以3.0 34 为例,
3.0 ** 34 == 16677181699666569
== 0b111011001111111100111011110011000100000011001010001001
默认浮点格式仅支持5 b <3>位的精度,但上面的数字需要5 b <4 b 位来表示,所以我们必须舍入最后一位位(1),导致
0b111011001111111100111011110011000100000011001010001000
^
== 16677181699666568
其中3的模数将返回2,这将打破循环并返回false。
(我还没有检查为什么它向下舍入而不是向上,但即使它向上舍入模数仍然不为零,所以它仍然会返回false。)
答案 1 :(得分:2)
考虑一下你的算法:你想要/=
做什么?
浮点除法?还是整数除法?你的问题清楚地使用前者,但是亲自尝试并看看它是否有效 - 你将继续除以base
并得到非整数。
在python 3中,整数除法是//
。