素性测试比较

问题描述

我在下面找到了一个新的素数测试,它可以确定 1000000007 是否是素数。

与其他现有素性算法相比,它的速度如何?
它是否赢得了最“在计算上毫无价值”的素性测试奖?

谢谢。

编辑

能够使用此处描述的这种方法提高速度:

https://math.stackexchange.com/questions/3979118/speedup-primality-test

“所以从 x=n/2 到 n/2+√n/2 就足够了。有了这个改进,你的算法仍然会比你的 isPrimeNumber 例程慢一些——只是因为计算 gcd 更慢而不是计算整除性。这对于测试可能有 15-20 位数字的数字是可行的,但是您需要完全不同的方法来测试更大的数字,例如您提到的 183 位数字。”

// Primality Test
// Every n is prime if all lattice points on x+y=n are visible from the origin.

#include <stdio.h>
#include <stdint.h>
#include <math.h>


uint64_t gcd(uint64_t a,uint64_t b)
{
    return (b != 0) ? gcd(b,a % b) : a;
}


int isPrimeNumber(uint64_t n)
{
    if (n == 1) return 0;
    if (n == 2 || n == 3) return 1;
    if (n % 2 == 0) return 0;

    // Start near line x=y.
    uint64_t x = (n / 2) + 2;
    uint64_t y = n - x;
    uint64_t count = sqrt(n) / 2;

    for (uint64_t i = 0; i < count; ++i) {
        // Check lattice point visibility...
        if (gcd(x,y) != 1) return 0;
        x++; y--;
    }

    return 1;
}


int main(int argc,char* argv)
{
    uint64_t n = 1000000007;

    if (isPrimeNumber(n) == 1)
    {
        printf("%llu prime.",n);
    }
    else
    {
        printf("%llu not prime.",n);
    }

    return 0;
}

解决方法

当您编写任何代码时,您应该进行基本的调试以验证您的代码是否符合您的预期。在几个小数字上运行你的代码;打印 xy 的值以验证它是否进行了正确的检查。

除此之外,如果您混合使用整数和浮点变量,您应该小心:隐式转换,例如从 floatunsigned 可能会导致数据丢失和完全错误的计算。编译器通常会对此发出警告;您应该在启用所有警告的情况下编译 -Wall 并注意编译器所说的内容。

看起来您在计算过程中应该始终使用 x + y = n - 这是您的不变量。这可以更容易地表达如下:

// initialization
x = n / 2;
y = n - x;
// it should be evident that your invariant holds here

do {
    ...
    x++; y--;
    // your invariant holds here too,by induction
}