C 确定N是否为素数(如果N为[2<;=N<;=2^63-1])的最佳算法是什么?

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 =

我尝试使用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 == 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
in
x=(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