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

Time:04-30

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.

My solution to this question is wrong and I can't figure out why at all. I am not that experienced so please if anyone can explain in a simple way why my code is wrong. What can I do to fix it??

CodePudding user response:

Note: I haven't hadn't included code in this answer because I figure the point of what you're doing is to learn to code these things. (Now you've gotten most of the way there, I did add a solution at the end.)


The problem is that your sums quickly go beyond the range of what JavaScript's number type can represent, reaching the point where they just are represented by Infinity. The number type only has 53 effective significant bits in which to hold numbers. You're exceeding that:

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);

You're doing four million (minus two) loops, but the question asks you to consider the Fibonacci numbers whose values are less than or equal to four million (4M), which is a very different thing and is reached much more quickly. So instead of (nearly) 4M loops, stop when your code determines that the next number is > 4M.

Also note that there's no reason to use an array for this, and doing so will consume a lot of memory unnecessarily. Instead, just remember the penultimate and ultimate values, and shuffle them in the loop. Maintain sum in the first loop rather than using a second one.


In a comment you showed that you'd solved it using an array but couldn't see how to solve it without using an array. Here's how to do that (see comments):

// 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);

  • Related