1.普通枚举所有因数
if(n<2) return 0;
if(n==2) return 1;
for(int i=2;i<=n/2;++i) if(!(n%i)) return 0;
return 1;
2.枚举所有因数对中较小的部分(到sqrt(n))
if(n<2) return 0;
if(n==2) return 1;
int tmp=sqrt(n)//注意,n为大整数时STL的sqrt会有精度误差,要手写二分求根
for(int i=2;i<=tmp;++i) if(n%i==0) return 0;
return 1;
3.模6法
if(n<2) return 0;
if(n==2) return 1;
if(n%6!=1&&n%6!=5) return 0;
int tmp=sqrt(n);
for(int i=5;i<=tmp;i+=6) if(n%i==0||num%(i+2)==0) return 0;
return 1;
4.费马素性测试
以费马小定理“如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)”
的逆命题“如果a^(p-1)≡1(mod p),整数a不是p的倍数,则p为素数”为原理,取任意a,以快
速幂计算结果,若为1,则该数为素数。
但会有一些数满足费马小定理的逆命题而不是素数,因此,引入随机数a做多次测试,即
Miller_rabin素性测试
5.Miller_rabin素性测试
long long fast_pow(long long x,long long y,int m)
{
long long res=1;
x%=m;
while(y)
{
if(y&1) res=(res*x)%m;
x=(x*x)%m;
y>>=1;
}
return res;
}
bool witness(long long a,long long n)
{
long long u=n-1;
int t=0;
while(u&1==0) u>>=1,t++;
long long x1,x2;
x1=fast_pow(a,u,n);
for(int i=1;i<=t;i++)
{
x2=fast_pow(x1,2,n);
if(x2==1&&x1!=1&&x1!=n-1) return true;
x1=x2;
}
if(x1!=1) return true;
else return false;
}
int miller_rabin(long long n,int s)
{
if(n<2) return 0;
if(n==2||n==3||n==5) return 1;
if(n%2==0||n%3==0||n%5==0) return 0;
for(int i=0;i<s&&i<n;i++)
{
long long a=rand()%(n-1)+1;
if(witness(a,n)) return 0;
}
return 1;
}