1

I wrote 3 simple implementations of factorials in JavaScript. When I compared them, I found out that they are not giving the same values. I've checked the logic in all, but I can't figure out why they are not equal to each other for some input values greater than 24.

Please take a look at my code and help me figure out why they differ and which implementation is correct? Thanks

function recursiveFactorial(n) {
    return n > 1 ? n * recursiveFactorial(n - 1) : 1;
}

function iterativeFactorial1(n) {
    let result = 1;

    while (n > 1) {
        result *= n;
        --n;
    }

    return result;
}

function iterativeFactorial2(n) {
    let result = 1;

    for (let i = 2; i <= n; ++i) {
        result *= i;
    }

    return result;
}

console.log('Iterative 1 vs Iterative 2');

for (let i = 1; i <= 50; ++i) {
    console.log(i, iterativeFactorial1(i) === iterativeFactorial2(i));
}

console.log('\nIterative 1 vs Recursive');

for (let i = 1; i <= 50; ++i) {
    console.log(i, iterativeFactorial1(i) === recursiveFactorial(i));
}

console.log('\nIterative 2 vs Recursive');

for (let i = 1; i <= 50; ++i) {
    console.log(i, iterativeFactorial2(i) === recursiveFactorial(i));
}

NOTE: After testing I found out that Iterative 2 and Recursive are giving same results but Iterative 1 and Recursive are giving different results which tells me that there's an issue with Iterative 1.

PS: I have updated the question since I forgot to put the recursive function as mentioned in the comments.

Fateslayer
  • 91
  • 7
  • 1
    It's a floating point issue isn't it? And yes both solutions are iterative. Recursion means a function which is calling itself until a certain condition is met. – kevinSpaceyIsKeyserSöze Jan 12 '21 at 16:21
  • 4
    Does this answer your question? [Large numbers erroneously rounded in JavaScript](https://stackoverflow.com/questions/1379934/large-numbers-erroneously-rounded-in-javascript) – kevinSpaceyIsKeyserSöze Jan 12 '21 at 16:24
  • 2
    Neither is recursive. To demonstrate that this is just rounding errors, note that they are the same if you use this loop: `for (let i = n; i > 1; --i) {result *= i}`. Or add a sprinkling of `BigInt`s in there to see it working properly as is. – Scott Sauyet Jan 12 '21 at 16:48
  • yeah my bad, neither is recursive but since both are iterative, why don't they give the same value? – Fateslayer Jan 13 '21 at 03:08
  • @Reger it doesn't make any difference cause === checks for type as well as value, while == checks for value only and tries to convert the type when possible to compare the values. – Fateslayer Jan 13 '21 at 03:29
  • @kevinSpaceyIsKeyserSöze i'm not sure if it's just rounding error cause even with rounding error, it should give the same result in both implementations. – Fateslayer Jan 13 '21 at 03:30
  • @Absolutely, I deleted the comments. So it was all about overflowing `Number.MAX_SAFE_INTEGER`. I forget from time to time that the factorial function creates such huge numbers – Reger Jan 14 '21 at 08:57

0 Answers0