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

Sid*_*rth 6 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));
Run Code Online (Sandbox Code Playgroud)

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

现在,我的问题是这个.为什么数字计算不正确,即使算法是完全理智的?我的想法指向JavaScript,因为根据谷歌的计算器 1,这两个数字相等.

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

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

Wil*_*eer 12

随着您的号码变大,您的丢失精度,实际上是JavaScript中的最大安全数量 Number.MAX_SAFE_INTEGER === 9007199254740991

对于所需的每个额外位,您将丢失1位精度,因为假设最后一位为零.

根据IEEE754 354224848179262000000等于二进制:

0 10001000011 0011001100111101101101110110101001111100010110010110
Run Code Online (Sandbox Code Playgroud)

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