3

I have a function:

function splitToDigits(n) {
    var digits = ("" + n).split("").map(function(item) {
        return parseInt(item, 10);
    });
    console.log(digits);
}

console.log(splitToDigits(123456784987654321));

This is returning digits = [1,2,3,4,5,6,7,8,4,9,8,7,6,5,4,3,2,0].

Any idea why the last element is 0? I noticed that when I delete 2 elements from the array it acts normally. Thanks for all the great answers! :)

gyre
  • 16,369
  • 3
  • 37
  • 47
Griffin Obeid
  • 87
  • 1
  • 9
  • 6
    it's instead of the `1` at the end of your number - because of precision limits in Numbers ... `console.log(123456784987654321)` to see the issue – Jaromanda X Mar 11 '17 at 03:53
  • You can check that with `Number.isSafeInteger`: `Number.isSafeInteger(123456784987654321)` is false, so you can’t necessarily distinguish it from other integers. – Ry- Mar 11 '17 at 03:55
  • 1
    Note that you could do `(''+n).split('').map(Number)` to save a bit of typing. ;-) – RobG Mar 11 '17 at 04:00

2 Answers2

1

As Jaromanda X mentioned in the comments section above, JavaScript does not have enough precision to keep track of every digit in the integer you passed to your function.

To fix this problem, you should instead pass a string:

console.log(splitToDigits('123456784987654321'))

However, I would also like to point out that you can greatly simplify your splitToDigits method:

function splitToDigits(n) {
  return [].map.call(n + '', Number)
}

console.log(splitToDigits('123456784987654321'))
console.log(splitToDigits(1234))
gyre
  • 16,369
  • 3
  • 37
  • 47
  • Ok, but if I go to parseInt() that same number in a different order later it will do the same thing? – Griffin Obeid Mar 11 '17 at 04:00
  • 1
    If you attempt to call `parseInt` on an integer that is too large to be stored in JavaScript, you will inevitably lose some precision. You can use a string instead, or just keep a list of digits using the method above. – gyre Mar 11 '17 at 04:02
1

It's because Javascript is truncating numbers.

The best way to see this is by doing this console.log:

function splitToDigits(n) {
console.log(n);
var digits = ("" + n).split("").map(function(item) {
    return parseInt(item, 10);
});
}

Then, when you ran: splitToDigits(123456784987654321), you already get 123456784987654320. Hence, it has nothing to do with your code as you have still not processed it.

If you add digits, it changes to scientific notation:

splitToDigits(1234567849876543211521521251) // turns to 1.2345678498765432e+27

It's a Javascript precision issue. That's all :)

nitobuendia
  • 1,228
  • 7
  • 18