我正在实施Wikipedia's Miller-Rabin algorithm,但似乎没有得到更模糊的结果。报道了7,11,19,23等复合材料。事实上,当k> 12时,偶数5显示为复合的。我已经读过Miller-Rabin背后的数学但是不太了解它并且盲目地依赖于算法。关于我哪里出错的任何线索?
这是我的代码:
#include<stdio.h>
#include<math.h>
int modpow(int b, int e, int m) {
long result = 1;
while (e > 0) {
if ((e & 1) == 1) {
result = (result * b) % m;
}
b = (b * b) % m;
e >>= 1;
}
return result;
}
int isPrime(long n,int k){
int a,s,d,r,i,x,loop;
if(n<2)return 0;
if(n==2||n==3)return 1;
if(n%2==0)return 0;
d=n-1;
s=0;
while(d&1==0){
d>>=1;
s++;
}
for(i=0;i<k;i++){
loop=0;
a=(int)(rand()*(n-1))+1;
x=modpow(a,d,n);
if(x==1 || x==n-1){
continue;
}
for(r=1;r<=s;r++){
x=modpow(x,2,n);
if(x==1)return 0;
if(x==n-1){
loop=1;
break;
}
}
if(!loop)return 0;
}
return 1;
}
int main(){
int i,k;
scanf("%d",&k);
for(i=5;i<100;i+=2){
printf("%d : %d\n",i,isPrime(i,k));
}
return 0;
}
答案 0 :(得分:4)
如果基数与候选人不相互作用,那么强大的费马检查总会返回“不是可能的素数”。
你的错误
a=(int)(rand()*(n-1))+1;
对于素数p
,基数不是p
(p
的倍数)的互质,当且仅当rand()
的结果具有< / p>
k*p + 1
对于小素数,即使迭代次数很少,也几乎可以保证这种情况发生。
基数应位于2 ans n/2
之间(选择大于n/2
的基数不是必需的,因为a
是复合性的见证,当且仅当n - a
是一个),所以你想要像
a = rand() % (n/2 - 2) + 2;
如果你不介意有利于小余数的随机数生成中的模偏差,或者
a = rand() /(RAND_MAX + 1.0) * (n/2 - 2) + 2;
如果你想在整个可能范围内分配偏差。