这年头,凡是能用编程语言写出来的大素数判定算法大部分都是概率性的,不能保证全部都对,但能够做到大部分正确。
提前声明一下,由于这里判定的是大素数,基本都要用到高精度(此处省略,用 int 代替 (python nb!) ,且次方皆用 pow 直接代替 因为我很懒 )。
所有的素性检验的第一步是排除比2大的偶数。~~~
此处的大素数定义为大于 1 0 9 10^9 109 的素数,均无法使用 O ( n ) O(\sqrt n) O(n) 的算法实现。
费马素性检验
众所周知,费马小定理
如果 p p p 是一个素数,且整数 a a a 不是 p p p 的倍数,
那么 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap−1≡1(modp)
反之,如果整数 a a a 不是 p p p 的倍数,且 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap−1≡1(modp) ,那么 p p p 是一个素数吗?
开头讲过:
不一定!
一个反例就是著名的 Carmichael 数。这一类数可以通过所有的费马素性检验,但它们是合数。所以这就是为什么费马素性检验是概率性的。但 Carmichael 数是很稀少的(最小的是561),所以该种方法可以在大部分情况下做出正确的判断。
选择一些比较小的数作为 a a a ,并依次带入费马小定理中。注意要多选一些,以使得正确率更大。只要有一个不通过就判定为合数。如果全部通过,则将该数判定为素数。
bool pd1(int p)
{
for(int i=2;i<=10;i++)
if(pow(i,p-1)%p!=1)//费马小定理
return false;
return true;
}
Miller-Rabin 素数测试算法
事实上,该算法是费马素性检验的加强版。
首先让我们引入二次探测定理
如果 p p p 是一个素数,且 0 &