gpt4 book ai didi

python - 为什么 pow(a, d, n) 比 a**d % n 快这么多?

转载 作者:IT老高 更新时间:2023-10-28 21:06:42 25 4
gpt4 key购买 nike

我试图实现 Miller-Rabin primality test ,并且对为什么中型数字(约 7 位数)需要这么长时间(> 20 秒)感到困惑。我最终发现以下代码行是问题的根源:

x = a**d % n

(其中 adn 都相似,但不相等,中等数字,** 是取幂运算符,% 是取模运算符)

然后我尝试将其替换为以下内容:

x = pow(a, d, n)

相比之下,它几乎是瞬时的。

关于上下文,这里是原始函数:

from random import randint

def primalityTest(n, k):
if n < 2:
return False
if n % 2 == 0:
return False
s = 0
d = n - 1
while d % 2 == 0:
s += 1
d >>= 1
for i in range(k):
rand = randint(2, n - 2)
x = rand**d % n # offending line
if x == 1 or x == n - 1:
continue
for r in range(s):
toReturn = True
x = pow(x, 2, n)
if x == 1:
return False
if x == n - 1:
toReturn = False
break
if toReturn:
return False
return True

print(primalityTest(2700643,1))

定时计算示例:

from timeit import timeit

a = 2505626
d = 1520321
n = 2700643

def testA():
print(a**d % n)

def testB():
print(pow(a, d, n))

print("time: %(time)fs" % {"time":timeit("testA()", setup="from __main__ import testA", number=1)})
print("time: %(time)fs" % {"time":timeit("testB()", setup="from __main__ import testB", number=1)})

输出(使用 PyPy 1.9.0 运行):

2642565
time: 23.785543s
2642565
time: 0.000030s

输出(使用 Python 3.3.0 运行,2.7.2 返回的时间非常相似):

2642565
time: 14.426975s
2642565
time: 0.000021s

还有一个相关的问题,为什么使用 Python 2 或 3 运行此计算几乎是使用 PyPy 的两倍,而通常 PyPy 为 much faster ?

最佳答案

参见维基百科文章 modular exponentiation .基本上,当您执行 a**d % n 时,您实际上必须计算 a**d,这可能非常大。但是有一些方法可以计算 a**d % n 而不必计算 a**d 本身,这就是 pow 所做的。 ** 运算符不能这样做,因为它无法“预见 future ”以知道您将立即取模。

关于python - 为什么 pow(a, d, n) 比 a**d % n 快这么多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14133806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com