精确和大数字

时间:2011-10-29 23:16:01

标签: javascript node.js precision

我在JavaScript中编写了一个函数来计算素数:

function isDivisible(dividend, divisor) {
    return dividend % divisor === 0;
}

function isPrime(n) {
    var factor = 2;

    n = Math.abs(n);

    if (n <= 1) {
        return true;
    }

    while (factor < n) {
        if (isDivisible(n, factor)) {
            return false;
        }

        factor += 1;
    }

    return true;
}
function getPrimes(max) {
    var primes = [], i = 1;

    while (i <= max) {
        if (isPrime(i)) {
            primes.push(i);
        }

        i += 1;
    }

    return primes;
}

function M(p) {
    return Math.pow(2, p) - 1;
}

function isMersennePrime(p) {
    var s, m, i;

    s = 4;
    m = M(p);

    for (i = 0; i < p - 2; i++) {
        s = (s * s - 2) % m;
    }

    return s === 0 ? true : false;
}

function findLargestMersennePrime(pMax) {
    var p, primes = getPrimes(pMax);

    while (primes.length) {
        p = primes.pop();

        if (isMersennePrime(p)) {
            return M(p);
        }
    }

    return null;
}

函数findLargestMersennePrime接受参数p,它用作计算Mersenne Prime数M(p)的种子值。该计划使用Lucas Lehmer Primality test

我使用的测试用例对应this table。对于任何给定的输入pMax,程序获得小于或等于pMax的素数列表,然后检查p的梅森数是否为素数。测试案例通过了前7个Mersenne Primes,即p&lt; 31。

当p = 31,61,89 ...时,M(p)是素数,但函数isMersennePrime(31)总是返回false。

我认为这可能与JavaScript中最大数量的大小有关。我正在运行Node 0.5。这是我的代码中的错误还是JavaScript的限制?是否有另一种语言更适合这个问题或者使它在JS中运行?

2 个答案:

答案 0 :(得分:4)

Javascript数字是标准的double precision floating numbers,并且最高可达2 52 - 1.这对于你的第8次梅森素数来说应该足够了(但对于第9次来说不够精确)< / p>

答案 1 :(得分:3)

一个内置大整数的语言(比如Python,Ruby,Scheme等)会让它变得更容易,但是有一些JavaScript的大整数库也可以工作。

一个缺点是您不能再使用普通的JavaScript运算符了。它也会比具有原生大整数的语言慢。

以下是几个例子: