python求最大素数_使用Python中的大素数

这篇博客探讨了高效检测素数的方法,包括使用mrange函数避免溢出错误,以及对比is_prime函数中all和notany的性能。文章提到了Miller-Rabin和Fermat算法在素性测试中的应用,特别指出对于寻找高质数,Miller-Rabin更适合。同时,提供了next_prime函数用于生成下一个素数,并强调了在处理大数时效率的重要性。最后,通过测试验证了算法的正确性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了确定一个数是否是素数,有一个筛子和素数检验。# for large numbers, xrange will throw an error.

# OverflowError: Python int too large to convert to C long

# to get over this:

def mrange(start, stop, step):

while start < stop:

yield start

start += step

# benchmarked on an old single-core system with 2GB RAM.

from math import sqrt

def is_prime(num):

if num == 2:

return True

if (num < 2) or (num % 2 == 0):

return False

return all(num % i for i in mrange(3, int(sqrt(num)) + 1, 2))

# benchmark is_prime(100**10-1) using mrange

# 10000 calls, 53191 per second.

# 60006 function calls in 0.190 seconds.

这似乎是最快的。有另一个版本使用not any,您可以看到def is_prime(num)

# ...

return not any(num % i == 0 for i in mrange(3, int(sqrt(num)) + 1, 2))

然而,在基准测试中,我在测试100**10-1是否是素数时,得到了70006 function calls in 0.272 seconds.而不是all60006 function calls in 0.190 seconds.的使用。

如果你需要找到下一个最高素数,这个方法对你不起作用。你需要进行素性测试,我发现Miller-Rabin算法是个不错的选择。它稍微慢一点Fermat方法,但对伪素数更准确。在这个系统上使用上述方法需要5分钟。

Miller-Rabin算法:from random import randrange

def is_prime(n, k=10):

if n == 2:

return True

if not n & 1:

return False

def check(a, s, d, n):

x = pow(a, d, n)

if x == 1:

return True

for i in xrange(s - 1):

if x == n - 1:

return True

x = pow(x, 2, n)

return x == n - 1

s = 0

d = n - 1

while d % 2 == 0:

d >>= 1

s += 1

for i in xrange(k):

a = randrange(2, n - 1)

if not check(a, s, d, n):

return False

return True

Fermat算法:def is_prime(num):

if num == 2:

return True

if not num & 1:

return False

return pow(2, num-1, num) == 1

要获得下一个最高质数:def next_prime(num):

if (not num & 1) and (num != 2):

num += 1

if is_prime(num):

num += 2

while True:

if is_prime(num):

break

num += 2

return num

print next_prime(100**10-1) # returns `100000000000000000039`

# benchmark next_prime(100**10-1) using Miller-Rabin algorithm.

1000 calls, 337 per second.

258669 function calls in 2.971 seconds

使用Fermat测试,我们得到了45006 function calls in 0.885 seconds.的基准,但是您运行伪素数的几率更高。

所以,如果只需要检查一个数字是否是素数,那么第一个方法is_prime就可以了。如果使用mrange方法,它是最快的。

理想情况下,您需要存储由next_prime生成的素数,然后从中读取。

例如,将next_prime与Miller-Rabin算法一起使用:print next_prime(10^301)

# prints in 2.9s on the old single-core system, opposed to fermat's 2.8s

1000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000000000000531

你不可能用return all(num % i for i in mrange(3, int(sqrt(num)) + 1, 2))及时完成这项工作。我在这个旧系统上都做不到。

为了确保next_prime(10^301)和Miller-Rabin产生正确的值,还使用Fermat和Solovay-Strassen算法对其进行了测试。

编辑:修复了next_prime中的错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值