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;
}