若n为素数,取a<n,设n-1=d*2^r,则要么a^d≡1(mod n),要么∃0≤i<r,s.t.(s.t.是满足或使得的意思)a^(d*2^i)≡-1(mod n).
思路:找k个数,全部进行上述两个测试(至少满足一个),若都能通过测试,则可以认为n是素数。
//该方法存在一定的问题,当然,出错的概率很小。
k个数选取:一般选取8个素数(zhx选的{2,3,5,7,11,13,17,37},他说这八个数判定long long以内的素数不会出错)
下面是伪代码(自己手敲,有错误请指出):
int prime[8]={2,3,5,7,11,13,17,37}; bool miller_rabin(int n,int a) { int d=n-1,r=0;//跟上述内容中的字母一致 while(d%2==0) d=d>>1,r++; int z=ksm(a,d,n)//快速幂求a^d%n的值 if(z==1) return true; for(int i=0;i<r;i++) { if(z==n-1) return true; z=1ll*z*z%n; } return false; } bool check(int n) { if(n<2) return false; for(int a=0;a<8;a++)//判断n是不是素数 { if(n==prime[n])//如果该数是素数表中的(prime)里的,直接返回true return true; if(n%prime{a}==0)//如果prime里有因子,直接返回false return false; if(!miller_rabin(n,prime[a])) return false;//如果素性测试返回的是false,则证明n不是素数 } return true;//如果能走到这一步,就说明n是素数。 }