为什么我的 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);
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);