【问题标题】:Good algorithms to determine whether one number is prime? [duplicate]确定一个数是否为素数的好算法? [复制]
【发布时间】:2010-09-07 14:04:19
【问题描述】:

可能重复:
Checking if an int is prime more efficiently

我需要测试一些非常大的整数,看看它是否是素数。能否提供一些好的算法或库例程?

编辑:C/C++ 可以。

谢谢。

【问题讨论】:

  • 多大才算非常大?
  • 奇怪,这个标题是那个标题的副本,但是这个问题不是那个问题的副本(它实际上想要测试不止一个素数)。
  • 要获得图书馆推荐,您需要选择一种语言或您可以使用的语言范围。 C?哈斯克尔? Javascript?

标签: algorithm primes


【解决方案1】:

Miller-Rabin test 非常快,对于特定范围的数字,它既快速又具有确定性。

【讨论】:

  • 我以前听说过这个,这个算法的运行时间也非常棒,谢谢你的链接!
  • openssl prime 使用 Miller-Rabin 算法。
【解决方案2】:

最简单的选择是使用现有的大整数库。它不会有bug,并且会提供所有的支持功能。

如果您正在编写自己的实现(即用于作业),我建议您使用书中的伪代码算法,以便您了解自己在做什么。

话虽如此,最简单的方法之一是使用 Jacobi 和 Legendre,并比较是否相等。我刚刚提交了一份 RSA 加密作业。这是我为单精度所做的,但是算法是通用的,也适用于多精度整数。

typedef uint64_t BigIntT;
typedef int64_t SBigIntT;

// This function calculations the power of b^e mod phi
// As long as 
//      b*b is smaller than max(BigIntT) 
//      b*phi is smaller than max(BigIntT)
// we will not have overflow.
BigIntT calculatePower (BigIntT b, BigIntT e, BigIntT m) {
    BigIntT result = 1;

    while (e != 0) {
        if (e & 1) {
            result = (result * b) % m;
        }

        e = e >> 1;
        b = (b * b) % m;
    }

    return result;
}

// This function implements simple jacobi test.
// We can expect compiler to perform tail-call optimisation.
SBigIntT jacobi (SBigIntT a, SBigIntT b) {
    if (a == 0 || a == 1) {
        return a;
    } else if (a % 2 == 0) {
        if (((b*b - 1) / 8) % 2 == 0) {
            return jacobi(a/2, b);
        } else {
            return -jacobi(a/2, b);
        }
    } else if ((((a-1) * (b-1)) / 4) % 2 == 0) {
        return jacobi(b % a, a);
    } else {
        return -jacobi(b % a, a);
    }
}

// This function implements : http://en.wikipedia.org/wiki/Solovay-Strassen_primality_test
bool testPrime (BigIntT p) {
    int tests = 10;

    if (p == 2) {
        return true;
    }

    while (tests-- > 0) {
        BigIntT a = generateRandomNumber(2, p);

        if (greatestCommonDivisor(a, p) == 1) {
            BigIntT l = calculatePower(a, (p-1)/2, p);
            SBigIntT j = jacobi(a, p);

            // j % p == l
            if ((j == -1) && (l == p-1) || (j == l)) {
                // So far so good...
            } else {
                // p is composite
                return false;
            }
        } else {
            // p is composite
            return false;
        }
    }

    return true;
}

【讨论】:

  • “我们可以期待编译器执行尾调用优化”——出于兴趣,你测试了吗?我不相信 C 编译器会进行尾调用优化,当然也不会在返回值为 -1 * 递归调用的结果时。
  • Steve,显然这取决于你的编译器的质量;不,我没有测试过。我只是希望任何足够先进的编译器都应该能够进行转换。
  • Steve,我刚刚在 LLVM 中对其进行了测试,它进行了尾调用优化:syntax-highlighting.com/p/show?id=1298
猜你喜欢
  • 2010-09-16
  • 2015-01-22
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 2013-07-06
  • 2020-04-13
  • 1970-01-01
相关资源
最近更新 更多