C 确定N是否为素数(如果N为[2<;=N<;=2^63-1])的最佳算法是什么?
我尝试使用Miller-Rabin算法,但它无法检测非常大的数字C 确定N是否为素数(如果N为[2<;=N<;=2^63-1])的最佳算法是什么?,c,primality-test,C,Primality Test,我尝试使用Miller-Rabin算法,但它无法检测非常大的数字 #include <stdio.h> #include <string.h> #include <stdlib.h> long long mulmod(long long a, long long b, long long mod) { long long x = 0,y = a % mod; while (b > 0) { if (b % 2 =
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
long long mulmod(long long a, long long b, long long mod)
{
long long x = 0,y = a % mod;
while (b > 0)
{
if (b % 2 == 1)
{
x = (x + y) % mod;
}
y = (y * 2) % mod;
b /= 2;
}
return x % mod;
}
long long modulo(long long base, long long exponent, long long mod)
{
long long x = 1;
long long y = base;
while (exponent > 0)
{
if (exponent % 2 == 1)
{
x = (x * y) % mod;
}
y = (y * y) % mod;
exponent = exponent / 2;
}
return x % mod;
}
int Miller(unsigned long long int p, int iteration)
{
int i;
long long s;
if (p < 2)
{
return 0;
}
if (p != 2 && p % 2==0)
{
return 0;
}
s = p - 1;
while (s % 2 == 0)
{
s /= 2;
}
for (i = 0; i < iteration; i++)
{
long long a = rand() % (p - 1) + 1, temp = s;
long long mod = modulo(a, temp, p);
while (temp != p - 1 && mod != 1 && mod != p - 1)
{
mod = mulmod(mod, mod, p);
temp *= 2;
}
if (mod != p - 1 && temp % 2 == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int iteration = 5, cases;
unsigned long long int num;
scanf("%d", &cases);
for(int i = 0; i < cases; i++)
{
scanf("%llu", &num);
if(Miller(num, iteration))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
我试图通过创建一个程序来完成我的家庭作业,这个程序告诉我一个数字是素数还是非素数,如果素数就打印是,如果不是就打印否。然而,每次我将代码提交给在线评委时,它只会说“错误答案”,而即使是我最后一次尝试做作业时,也没有任何有效的算法,它会说“超出了时间限制”
当N为[2]时,有没有办法确定N是否为素数?OP的代码有许多可能溢出63位数学。例如,
x*y
inx=(x*y)%mod;
至少,建议转到无符号数学。例如:long-long
-->unsigned-long-long
或干脆uintmax\t
对于未溢出的mulmod()
:
稍后我将对此进行更多研究。GTG。请提供一个此类输入的示例
返回x%mod;
可以写成返回x;
因为x
总是更新%mod
(可能编译器优化了它…但为什么信任编译器?)。您得到的最大可能素数P小于2^63,对于给定的N,您计算N^(P-1)mod P并查看它是否为1。在Linux上,您可以找到几个开源素数生成器(例如primesife bin
包)。还可以阅读wikipage On.Read以及您的C编译器(例如…)和调试器(例如…)的文档Miller-Rabin的全部观点是将非常大的素数从复合数中分离出来;小于64位的数字根本不是“非常大”。如果您正确地实现它,Miller-Rabin将绝对有效。
10 //cases
1
NO
2
YES
3
YES
4
NO
5
YES
1299827
YES
1951
YES
379
YES
3380
NO
12102
NO