费马小定理与素数判定

      费马小定理是初等数论四大定理(威尔逊定理欧拉定理(数论中的欧拉定理,即欧拉函数),中国剩余定理和费马小定理)之一,在初等数论中有着非常广泛和重要的应用。实际上,它是欧拉定理的一个特殊情况。

      其内容为: 假如p是质数,且GCD(a,p)=1,那么 a^(p-1) ≡1(mod p)(假如p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1)

      证明:大数取余的公式 (a*b)%mod =(a%mod * b%mod) %mod, 设P为素数 那么  (a*k) %p =(a%p*k) % P   [1<=k<=p-1]  ;a%p=c是个定值,由于p是个素数,所以(a%p*k) % P的值互不相同,如果存在 (c*i) %p == (c*j) %p  (i<j) 那么 c*i +p*t == c*j ,  说明 c = a%p 可以被 p 整除 ,显然不成立; (a*k) %p的值在[1,p-1]中取,既然互不相同,所以 (a*k) %p的值覆盖了 [1,p-1] 中的所有数,则 (a*1) %p * (a*2) %p * (a*3) %p * ... * (a*(p-1)) %p = 1*2*3*...*(p-1) =(a^(p-1))%p *1*2*3*...*(p-1)  ==> (a^(p-1))%p=1 证毕。

     用费马小定理的逆命题可以来判定素数,但是其逆命题不一定成立,所以有一定的概率,需要多次测试来减小出错的概率。每次测试随机取一个正整数a,要保证 GCD(a,p)=1; 用快速幂来计算a^(p-1) 看是否为 1,如果为1则通过这次测试。     但是这样也可能出错,因为存在称做Carmichael数的数,使得对这些合数进行多次测试都能通过,但是它们不是素数。前3个Carmichael数是561,1105,1729。Carmichael数是非常少的。在1~100000000范围内的整数中,只有255个Carmichael数。利用二次探测定理可以对上面的素数判定算法作进一步改进,以避免将Carmichael数当作素数。

     二次探测定理 如果p是一个素数,且0<x<p,则方程x^2≡1(mod p)的解必为 x=1或p-1。

 

 1 long long gcd(long long a,long long b)
 2 {
 3     if (b==0) return a;
 4     return gcd(b,a%b);
 5 }
 6 long long Qpower(long long a,long long b,long long mod)
 7 {
 8       if (b==1) return a%mod;
 9       if (b&1) return ((a%mod)*Qpower(a,b-1,mod))%mod;
10       long long t=Qpower(a,b>>1,mod);
11       long long tt=(t*t)%mod;
12       if (tt==1)   // 二次探测
13       {
14           if (t!=1 && t!=mod-1) iff=false;
15       }
16       return tt;
17 }
18 bool ifp(long long p)
19 {
20     int T=30;
21     iff=true;
22     while (T--)
23     {
24         long long a=rand()%10000*rand()+1; //不能取0
25         while (gcd(a,p)!=1){ if (a<p || a%p!=0) return false;a=rand()%1000*rand()+1;}
26         if (Qpower(a,p-1,p)!=1|| !iff) return false;
27     }
28     return true;
29 }
素数判定代码

 

还有更高效的方法来判定素数。

 

posted @ 2013-08-12 15:57  wuminye  阅读(3071)  评论(0编辑  收藏  举报