9

我正在研究 Rosalind 问题Mortal Fibonacci Rabbits,当我使用我的算法编写的 JavaScript 时,网站一直告诉我我的答案是错误的。当我在 Python 中使用相同的算法时,我得到了不同的(正确的)答案。

只有当结果变大时才会发生不一致。例如在 JavaScript 中fibd(90, 19)返回2870048561233730600,但在 Python 中我得到2870048561233731259.

JavaScript 中的数字是否给了我不同的答案,或者在我的 JavaScript 代码中犯了一个微妙的错误?

JavaScript 解决方案:

function fibd(n, m) {
    // Create an array of length m and set all elements to 0
    var rp = new Array(m);
    rp = rp.map(function(e) { return 0; });
    rp[0] = 1;

    for (var i = 1; i < n; i++) {
        // prepend the sum of all elements from 1 to the end of the array
        rp.splice(0, 0, rp.reduce(function (e, s) { return s + e; }) - rp[0]);
        // Remove the final element
        rp.pop();
    }

    // Sum up all the elements
    return rp.reduce(function (e, s) { return s + e; });
}

Python解决方案:

def fibd(n, m):
    # Create an array of length m and set all elements to 0
    rp = [0] * m
    rp[0] = 1

    for i in range(n-1):
        # The sum of all elements from 1 the end and dropping the final element
        rp = [sum(rp[1:])] + rp[:-1]

    return sum(rp)
4

2 回答 2

13

我认为 Javascript 只有一个“数字”数据类型,这实际上是一个 IEEE 双引擎盖。2,870,048,561,233,730,600 太大而无法在 IEEE double 中精确保存,因此它是近似的。(注意尾随的“00” - 小数点后 17 位大约适合双精度。)

另一方面,Python 支持 bignum,并且会非常乐意地处理 4096 位整数(对于那些玩弄加密算法的人来说,这是一个巨大的福音)。

可能如果您搜索,将能够找到一个 Javascript bignum 库 - 例如http://silentmatt.com/biginteger/

于 2015-12-10T09:17:53.607 回答
7

只是做了一些研究,这篇文章似乎很有趣。Javascript 仅支持 53 位整数。

Python给出的结果确实超出了JS的最大安全范围。如果你尝试做

parseInt('2870048561233731259')

它确实会回来

2870048561233731000
于 2015-12-10T09:27:51.237 回答