#4
by かびるん » 8年前
なるほど。ありがとうございます。
unsigned long long型を双方に適用して、型の最大値の平方根 4294967295 までの素数判定が決定的になることがわかりました。
(とりあえず1億まで数え上げさせたら、個数が一致しました)
それと、判定の底が間違ってたみたいなので直しました。
コード:
// 底を2,7,61にしてMiller–Rabin素数判定法を用いると、
// 2^32までの素数判定は決定的であることが保証されている.
#include<stdio.h>
#include<math.h>
#define ullint unsigned long long int
// 冪剰余(a^b %d の計算)
int modpow(ullint a, ullint b, int d) {
if (b == 0) return 1;
if (b % 2 == 0) return modpow(a*a % d, b/2, d);
else return a*modpow(a, b-1, d) % d;
}
bool Miller_Rabin_Test(int n){
int prime_list[4] = {2, 7, 61};
if(n == 2 || n == 7 || n == 61){ // 2,7,61は素数
return true;
}
if(n == 1 || n%2 == 0){ // 2以外の偶数と1は素数でない
return false;
}
// n = 2^s*d + 1 (dは奇数)の形に変形
int d = n-1;
int s = 0;
while(d%2 == 0){ // dが奇数になるまで変形
d = d/2;
s++;
}
for(int i=0; i<3; i++){ // 判定する底は3つ
bool isProbPrime = false;
int a = prime_list[i];
int r = modpow(a, d, n);
if(r == 1 || r == n-1){
isProbPrime = true;
}
for(int j=0; j<s; j++){
r = modpow(a, pow(2,j)*d, n);
if(r == n-1){
isProbPrime = true;
}
}
if(!isProbPrime){
return false;
}
}
return true;
}
int main(){
int n = 0;
scanf_s("%d",&n);
if(Miller_Rabin_Test(n)){
printf("%d is prime\n",n);
}else{
printf("%d is not prime\n",n);
}
return 0;
}
なるほど。ありがとうございます。
unsigned long long型を双方に適用して、型の最大値の平方根 4294967295 までの素数判定が決定的になることがわかりました。
(とりあえず1億まで数え上げさせたら、個数が一致しました)
それと、判定の底が間違ってたみたいなので直しました。
[code]
// 底を2,7,61にしてMiller–Rabin素数判定法を用いると、
// 2^32までの素数判定は決定的であることが保証されている.
#include<stdio.h>
#include<math.h>
#define ullint unsigned long long int
// 冪剰余(a^b %d の計算)
int modpow(ullint a, ullint b, int d) {
if (b == 0) return 1;
if (b % 2 == 0) return modpow(a*a % d, b/2, d);
else return a*modpow(a, b-1, d) % d;
}
bool Miller_Rabin_Test(int n){
int prime_list[4] = {2, 7, 61};
if(n == 2 || n == 7 || n == 61){ // 2,7,61は素数
return true;
}
if(n == 1 || n%2 == 0){ // 2以外の偶数と1は素数でない
return false;
}
// n = 2^s*d + 1 (dは奇数)の形に変形
int d = n-1;
int s = 0;
while(d%2 == 0){ // dが奇数になるまで変形
d = d/2;
s++;
}
for(int i=0; i<3; i++){ // 判定する底は3つ
bool isProbPrime = false;
int a = prime_list[i];
int r = modpow(a, d, n);
if(r == 1 || r == n-1){
isProbPrime = true;
}
for(int j=0; j<s; j++){
r = modpow(a, pow(2,j)*d, n);
if(r == n-1){
isProbPrime = true;
}
}
if(!isProbPrime){
return false;
}
}
return true;
}
int main(){
int n = 0;
scanf_s("%d",&n);
if(Miller_Rabin_Test(n)){
printf("%d is prime\n",n);
}else{
printf("%d is not prime\n",n);
}
return 0;
}
[/code]