/*
测试大素数
1.筛选法+试除法
2.Miller_Rabin方法
*/
/*
下面是Miller_Rabin方法
1.如果n是素数,且与a互质,则a^(n-1)≡1(mod n)(1<=a<=n);
2.由于a≡a(mod n) =>a^n≡a(mod n)
3.但是满足a^(n-1)≡1(mod n)的n不一定是素数
4.想要知道n是否为素数,还需不断选取a,有可能出现伪素数
5.时间复杂度0(k*(log2)^3(n))
6.如果a^2≡1(mod n) 则必有a≡1(mod n)或者a≡n-1(mod n);
现在如果有一个大于2的质数n,零n-1=2^s*d,其中d为奇数,
则根据费马小定理,如果a不能被素数n整除,则a^(n-1)≡1(mod n);
==>a^d≡1(mod n)或者a^2≡1(mod n),a^(2^r*d)≡n-1( mod n),0<=r<=s,其中a为任意自然数。
这样,我们只要找到一个a,满足a^!≡1(mod n)
或者存在一个自然数r(0<=r<=s),使a^(2^r*d)!≡n-1( mod n),就可以说明不是素数
7.事实上经过反复的实验,可以得出这样一个结论:
对于32位内的任何一个整数n,如果其通过了一2,7,61为底的Miller-Rabin测试,那么n一定是素数,反之则一定不是
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<time.h>
using namespace std;
__int64 qpow(__int64 a,__int64 b,__int64 M)
{
__int64 ans=1;
while(b)
{
if(b&1) ans*a,ans%=M;
a*=a;a%=M;b>>=1;
}
return ans;
}
bool MillerRabinTest(__int64 x,__int64 n)
{
__int64 y=n-1;
while(!(y&1)) y>>=1;
x=qpow(x,y,n);
while(y<n-1&&x!=1&&x!=n-1)
{
x=(x*x)%n,y<<=(__int64)1;
}
return x==n-1||y&1==1;
}
bool isprime32(__int64 n)
{
if(n==2||n==7||n==61) return 1;
if(n==1||(n&1)==0) return 0;
return MillerRabinTest(2,n)&&MillerRabinTest(7,n)&&MillerRabinTest(61,n);
}
int main()
{
for(int i=2;i<=100;i++)
{
if(isprime32(i))
{
cout<<i<<endl;
}
}
cout<<"Time:"<<clock()<<endl;
return 0;
}
测试大素数
最新推荐文章于 2023-01-15 11:47:12 发布