大数素性检验

大数素性检验:

  1 #include <iostream>
  2 #include <stdlib.h>
  3 //#include "big.h"
  4 
  5 //#pragma comment(lib, "miracl.lib")
  6 using namespace std;
  7 
  8 // Montgomery 快速幂模算法(n^p)%m
  9 unsigned __int64 Montgomery(unsigned __int64 n, unsigned __int64 p, unsigned __int64 m)
 10 {
 11     unsigned __int64 r = n % m;
 12     unsigned __int64 k = 1;
 13     while (p > 1)
 14     {
 15         if ((p & 1) != 0)
 16         {
 17             k = (k * r) % m; 
 18         }
 19         r = (r * r) % m;    
 20         p >>= 1;
 21     }
 22     return (r * k) % m;        
 23 }
 24 
 25 // 返回true:n是合数, 返回false:n是素数 
 26 bool R_M_Help(unsigned __int64 a, unsigned __int64 k, unsigned __int64 q, unsigned __int64 n)
 27 {
 28     if (1 != Montgomery(a, q, n))
 29     {
 30         int e = 1;
 31         for (int i = 0; i < k; ++i)
 32         {
 33             if (n - 1 == Montgomery(a, q * e, n))
 34                 return false;
 35             e <<= 1;
 36         }
 37         return true;
 38     }
 39     return false;
 40 }
 41 
 42 //拉宾-米勒测试 返回true:n是合数, 返回false:n是素数 
 43 bool R_M(unsigned __int64 n)
 44 {
 45     if (n < 2)
 46         throw 0;
 47     if (n == 2 || n == 3)
 48     {
 49         return false;
 50     }
 51     if ((n & 1) == 0)
 52         return true;
 53 
 54     // 找到k和q, n = 2^k * q + 1; 
 55     unsigned __int64 k = 0, q = n - 1;
 56     while (0 == (q & 1))
 57     {
 58         q >>= 1;
 59         k++;
 60     }
 61     /*if n < 1,373,653, it is enough to test a = 2 and 3.
 62     if n < 9,080,191, it is enough to test a = 31 and 73.
 63     if n < 4,759,123,141, it is enough to test a = 2, 7, and 61.
 64     if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11.*/
 65     if (n < 1373653)
 66     {
 67         if (R_M_Help(2, k, q, n) || R_M_Help(3, k, q, n))
 68             return true;
 69     }
 70     else if (n < 9080191)
 71     {
 72         if (R_M_Help(31, k, q, n) || R_M_Help(73, k, q, n))
 73             return true;
 74     }
 75     else if (n < 4759123141)
 76     {
 77         if (R_M_Help(2, k, q, n)
 78             || R_M_Help(3, k, q, n)
 79             || R_M_Help(5, k, q, n)
 80             || R_M_Help(11, k, q, n))
 81             return true;
 82     }
 83     else if (n < 2152302898747)
 84     {
 85         if (R_M_Help(2, k, q, n)
 86             || R_M_Help(3, k, q, n)
 87             || R_M_Help(5, k, q, n)
 88             || R_M_Help(7, k, q, n)
 89             || R_M_Help(11, k, q, n))
 90             return true;
 91     }
 92     else
 93     {
 94         if (R_M_Help(2, k, q, n)
 95             || R_M_Help(3, k, q, n)
 96             || R_M_Help(5, k, q, n)
 97             || R_M_Help(7, k, q, n)
 98             || R_M_Help(11, k, q, n)
 99             || R_M_Help(31, k, q, n)
100             || R_M_Help(61, k, q, n)
101             || R_M_Help(73, k, q, n))
102             return true;
103     }
104     return false;
105 }
106 
107 int main()
108 {
109     ////初始化一个500位10进制的大数系统
110     //Miracl precision(500, 10);
111     //char a[512];
112     //memset(a, 0, 512);
113 
114     //big p = mirvar(0); //大素数p
115     //expb2(100, p);
116 
117     //while (1)
118     //{
119     //    // nxprime(pd,x)找到一个x大于pd的素数,返回值为BOOL
120     //    nxprime(p, p);
121 
122     //    // 将一个大数根据其进制转换成一个字符串
123     //    cotstr(p, a);
124     //    if (isprime(p)) 
125     //        cout << "p is a prime!" << "\n" << a << "\n";
126     //    getchar();
127 
128     //}
129     
130     long long num;
131     while (1)
132     {
133         scanf_s("%lld",&num);
134         if (!R_M(num))
135         {
136             cout << "Is prime num." << endl;
137         }
138         else
139         {
140             cout << "No." << endl;
141         }
142 
143     }
144 
145     return 0;
146 }

 

posted @ 2015-05-11 18:52  ht-beyond  阅读(876)  评论(0编辑  收藏  举报