【问题标题】:Primality Test Comparison [closed]素性测试比较[关闭]
【发布时间】:2021-01-03 16:00:22
【问题描述】:

我在下面发现了一个新的素数测试,它可以确定 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;
}

【问题讨论】:

  • 你说的是计算复杂度吗?正确性?还有什么?
  • 对于素数,它必须测试 x,y 的大约 n/2 值,但对于合数,您可能会很幸运并找到早期结果。
  • 程序报告1000000007不是素数,但它是。
  • 仅在 [2, sqrt(n)] 范围内检查 gcd(x,y) 中的 x。改进! &lt;/sarcasm&gt;

标签: c primes primality-test


【解决方案1】:

当您编写任何代码时,您应该进行基本调试以验证您的代码是否按照您的想法进行。在几个小数字上运行您的代码;打印 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
}

【讨论】:

  • 对程序进行这些修改后,它现在可以正确地将 1000000007 报告为素数,但在我的机器上需要 90 秒。而使用 sqrt(n) 的除数的试验除法只需要几分之一秒。
猜你喜欢
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2022-12-17
  • 2013-10-11
  • 2016-07-18
  • 1970-01-01
相关资源
最近更新 更多