为什么我的 JavaScript 问题 2(欧拉项目)的解决方案在控制台上显示无穷大?

Why does my JavaScript solution to problem 2 (project euler) show infinity on the console?

let arr=[0,1];
let sum=0;
for(let i=2;i<4000000;i++) {
    arr.push(arr[i-1]+arr[i-2]);
}

for (let i=0;i<arr.length;i++) {
    if (arr[i]%2==0) {
        sum+=arr[i];
    }
}

console.log(sum);

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

我对这道题的解答是错误的,我完全想不通为什么。我不是那么有经验,所以如果有人能以简单的方式解释为什么我的代码是错误的,请。我能做些什么来修复它??

注意:没有没有在这个答案中包含代码,因为我认为您正在做的事情的重点是学习对这些东西进行编码。 (现在你已经完成了大部分,我在最后添加了一个解决方案。)


问题是您的总和很快就超出了 JavaScript 的数字类型可以表示的范围,达到了它们只能由 Infinity 表示的程度。 number 类型只有 53 个有效有效位来保存数字。你超过了:

let seen4M = false;
let seenInfinity = false;
let arr=[0,1];
let sum=0;
for(let i=2;i<4000000;i++) {
    const num = arr[i-1]+arr[i-2];
    if (!seen4M && num > 4_000_000) {
        console.log(`Too big: ${num}`);
        seen4M = true;
    } else if (!seenInfinity && !isFinite(num)) {
        console.log(`Overflowed just after ${arr[i-1]}`);
        seenInfinity = true;
    }
    arr.push(num);
}

for (let i=0;i<arr.length;i++) {
    if (arr[i]%2==0) {
        sum+=arr[i];
    }
}

console.log(sum);

你正在做四百万(减二)循环,但问题要求你考虑值小于或等于四百万(4M)的斐波那契数,这是一个非常不同的事情并且达到了快得多。因此,不是(接近)4M 循环,而是在您的代码确定下一个数字大于 4M 时停止。

另请注意,没有理由为此使用数组,这样做会不必要地消耗 很多 内存。相反,只需记住倒数第二个和最终的值,并在循环中洗牌。在第一个循环中保持 sum 而不是使用第二个循环。


在评论中,您表明您已使用数组解决了它,但看不到如何在不使用数组的情况下解决它。以下是如何做到这一点(见评论):

// The penultimate (second-to-last) Fibonacci number we've done
let pen = 0;
// The ultimate (last) Fibonacci number we've done
let ult = 1;
// The sum so far
let sum = 0;
// A variable for each number as we go
let num;

// Create the next number and keep looping if it's less than or
// equal to four million
while ((num = pen + ult) <= 4_000_000) {
    // We have a new number (`num`), count it if appropriate
    if (num % 2 == 0) {
        sum += num;
    }
    
    // Now that we have a new number, shuffle the last two:
    // our ultimate number is our penultimate number, and
    // our ultimate number is the new one
    pen = ult;
    ult = num;
}
console.log(sum);