所以,我开始尝试使用递归函数找到第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上测试了这个。
答案 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个有效数字的精确度。