【发布时间】:2020-05-01 03:20:27
【问题描述】:
我正在做一个项目,该项目需要我找出极大的数字是否是素数。当然,我已经阅读了如何找到素数并提出了一个非常简单的蛮力方法:
def is_prime_brute_force(p):
if p == 2 or p == 3:
return true
if p == 1 or p % 2 == 0 or any(p % i == 0 for i in range(3, floor_sqrt(p), 2)):
return false
return true
我还研究了诸如Miller-Rabin Primality Test 和费马小定理之类的概率方法(请参阅here 了解 Rosetta 代码对前者的实现)。
虽然概率选项比蛮力快一个数量级,但对于 n 的非常大的输入(例如,已知的素数 10**9999 + 33603),它们仍然非常慢。
我遇到了一个有趣的观察结果(当然我不是第一个遇到这种观察结果的人),即 所有 素数都符合 p = 6 * k + 1 或 p = 6 * k -1 等式。在 Python 中,这样的函数是这样的
def is_prime_eq(p):
if p == 2 or p == 3:
return True
if p == 0 or p == 1:
return False
# The same as `return (p % 6 == 1) or (p % 6 == 5)`
prime_test = lambda p, a, m : (p % a == m) or (p % a == (a-m))
return prime_test(p, 6, 1)
如果p 是素数,上述保证返回真,但真结果并不意味着p 是素数。一个简单的例子是 25(25 = 1 (mod 6),但显然 25 = 5^2)。
我想知道是否有一些更通用的方法来应用素数的这个有趣的属性,也许使用不同的a 值来提高我的is_prime 函数的速度。
【问题讨论】:
-
只需使用概率测试。理想情况下,其他人已经实施了。
-
尽管整数 k 的所有素数(除了 2 或 3)都是 6k+1 或 6k-1 的形式,但并非所有 6k+1 或 6k-1 形式的数都是素数。
-
@enumaris 谢谢,我忘了包括那个细节。我已经更新了问题。
-
您可能会发现this question 的答案很有帮助。
-
...概率选项的速度要快一个数量级...本世纪的轻描淡写。