1

I created the following code to calculate numbers multiplied by eleven using the method I learnt in elementary school:

function multiplyby11(number) {
    var num = number + "";
    var integers = num.split('');
    var numbers = [];
    integers.forEach(function (val) {
        numbers.push(parseInt(val));
    });
    var multiply = [];
    multiply.push(numbers[0]);
    var number_length = numbers.length;
    for (var i = 1; i < number_length; ++i) {
        multiply.push(numbers[i] + numbers[i - 1])
    }
    multiply.push(numbers[number_length - 1]);

    function removeAllMultiplesOfTen() {
        var allRemoved = true;
        multiply.forEach(function (val, index) {
            if (val >= 10) {
                val -= 10;
                multiply[index - 1]++;
                multiply[index] = val;
                allRemoved = false;
            }
        });
        if (!allRemoved) {
            removeAllMultiplesOfTen();
        }
    }

    removeAllMultiplesOfTen();
    return multiply.join('');
}

If I input a number like 15487548796454858 my code returns

170363036761003438

But if I just do a plain javascript calculation of 15487548796454858 * 11 it returns:

170363036761003420

which is completely incorrect.

Am I running into some sort of number overflow in javascript, or did I miss something?

qwertynl
  • 3,912
  • 1
  • 21
  • 43
  • 2
    could it be related? http://stackoverflow.com/questions/307179/what-is-javascripts-max-int-whats-the-highest-integer-value-a-number-can-go-t – Saturnix Nov 27 '13 at 16:39
  • If you do `alert(170363036761003438)` (or just paste the number in your JS console), you'll see that JS can't represent that value as a number at all. Your function works because your final result is a string and your algorithm deals with `Number` values low enough that there's no loss of precision. – apsillers Nov 27 '13 at 16:51
  • Hmmm Interesting. So there is a weird number overflow... – qwertynl Nov 27 '13 at 16:56
  • Yes, the floating point number's mantissa component "overflows". (Floating point numbers are stored as `mantissa * (2 ^ exponent)`.) We can still express *bigger* numbers by increasing the exponent, but we cannot express *more precise* numbers. – apsillers Nov 27 '13 at 17:01

1 Answers1

3

In Javascript numbers are double precision floating point numbers.

That means that the precision is about 15 digits. As your calculation has 18 digits, only the first 15 are correct.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 1
    So the only way to multiply numbers that are greater than 18 digits is to make a multiply hack like I did then? – qwertynl Nov 27 '13 at 16:46
  • 2
    @qwertynl You should use a [bignum library](https://github.com/jtobey/javascript-bignum) that will handle the hacks for you. :) – apsillers Nov 27 '13 at 16:49