Where_Free

羸弱 无知 自大 懒惰

Miller_Rabin算法_单个素数检测_启发式算法

 1 /**
 2 Miller_Rabin 算法进行素数测试
 3 快速判断一个<2^63的数是不是素数,主要是根据费马小定理
 4 */
 5 #define ll __int128
 6 const int S=8; ///随机化算法判定次数
 7 ll MOD;
 8 ///计算ret=(a*b)%c  a,b,c<2^63
 9 ll mult_mod(ll a,ll b,ll c)
10 {
11     a%=c;
12     b%=c;
13     ll ret=0;
14     ll temp=a;
15     while(b)
16     {
17         if(b&1)
18         {
19             ret+=temp;
20             if(ret>c)
21                 ret-=c;//直接取模慢很多
22         }
23         temp<<=1;
24         if(temp>c)
25             temp-=c;
26         b>>=1;
27     }
28     return ret;
29 }
30 
31 ///计算ret=(a^n)%mod
32 ll pow_mod(ll a,ll n,ll mod)
33 {
34     ll ret=1;
35     ll temp=a%mod;
36     while(n)
37     {
38         if(n&1)
39             ret=mult_mod(ret,temp,mod);
40         temp=mult_mod(temp,temp,mod);
41         n>>=1;
42     }
43     return ret;
44 }
45 
46 ///通过费马小定理 a^(n-1)=1(mod n)来判断n是否为素数
47 ///中间使用了二次判断,令n-1=x*2^t
48 ///是合数返回true,不一定是合数返回false
49 bool check(ll a,ll n,ll x,ll t)
50 {
51     ll ret=pow_mod(a,x,n);
52     ll last=ret;//记录上一次的x
53     for(int i=1;i<=t;i++)
54     {
55         ret=mult_mod(ret,ret,n);
56         if(ret==1&&last!=1&&last!=n-1)
57             return true;//二次判断为是合数
58         last=ret;
59     }
60     if(ret!=1)
61         return true;//是合数,费马小定理
62     return false;
63 }
64 
65 
66 ///Miller_Rabbin算法
67 ///是素数返回true(可能是伪素数),否则返回false
68 bool Miller_Rabbin(ll n)
69 {
70     if(n<2) return false;
71     if(n==2) return true;
72     if((n&1)==0) return false;//偶数
73     ll x=n-1;
74     ll t=0;
75     while((x&1)==0)
76     {
77         x>>=1;
78         t++;
79     }
80     srand(time(NULL));
81     for(int i=0;i<S;i++)
82     {
83         ll a=rand()%(n-1)+1; // 生成随机数 0<a<=n-1  去试试
84         if(check(a,n,x,t))
85             return false;
86     }
87     return true;
88 }

 

posted on 2019-07-30 13:07  Where_Free  阅读(143)  评论(0编辑  收藏  举报

导航