为什么JavaScript认为354224848179262000000和354224848179261915075相等?

时间:2014-08-21 17:39:08

标签: javascript

所以,我开始尝试使用递归函数找到第100个Fibonacci数,并使用以下代码记忆该函数。

Function.prototype.memoize = function () {
    var originalFunction = this,
        slice = Array.prototype.slice;
        cache = {};
    return function () {
        var key = slice.call(arguments);
        if (key in cache) {
            return cache[key];
        } else {
            return cache[key] = originalFunction.apply(this, key);
        }
    };
};

var fibonacci = function (n) {
    return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}.memoize();

console.log(fibonacci(100));

现在,正如您在this小提琴中看到的那样,JavaScript会记录 354224848179262000000 作为结果。根据{{​​3}},第100个斐波纳契数实际上是 354224848179261915075 。这是正确的。

现在,我的问题是这个。 为什么数字计算错误,即使算法完全正确?我的想法指向JavaScript,因为根据WolframAlpha 1 ,这两个数字是相等的。

导致此类错误的JavaScript是什么?该数字安全地在IEEE 754号码的最大值范围内, 1.7976931348623157e + 308

1 如果这可能是我平台上的错误,我已经在Ubuntu上的Chromium和Firefox上测试了这个。

2 个答案:

答案 0 :(得分:12)

随着您的号码越来越大,您的丢失精确度,JavaScript中的最大安全数量实际为Number.MAX_SAFE_INTEGER === 9007199254740991

对于每个需要的额外位,您将失去1位精度,因为最后一位被假定为零。

根据IEEE754 354224848179262000000等于二进制:

0 10001000011 0011001100111101101101110110101001111100010110010110

指数10001000011是1091,如果减去1023则结果为68 这意味着您使用68位来表示有效值,因为它们只有52位可用于有效位,后16位假定为零。 任何落在这16位的计算都没有效果。

答案 1 :(得分:4)

因为IEEE-754 double precision floating point仅提供15到17个有效数字的精确度。