menu

Questions & Answers

Why function returns wrong array of numbers if that number is big

I am working to solve a problem, I have an array of numbers for example [1, 2, 3] and I need to make from that array number 123 and add 1 and than return it like [1, 2, 4]. My code work with small numbers but with big it returns wrong number. Why?

var plusOne = function(digits) {
  let num = parseInt(digits.join(''))
  num = num + 1
  let arr = num.toString().split().join(',')
  let incrementedArr = []
  for (let i = 0; i < arr.length; i++) {
    incrementedArr.push(arr[i])
  }

  return incrementedArr;
};

When input is

[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]

my function returns

[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,0,0,0]

instead of

[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,4]

why I have three zeros in the end? Thank you!

Comments:
2023-01-17 00:46:59
You're exceeding the maximum precision of JavaScript numbers when you concatenate all the digits.
2023-01-17 00:46:59
parseInt('6145390195186705543') -> 6145390195186705000 - because numbers can't be so big in javascript
2023-01-17 00:46:59
You could do this if you use BigInt
2023-01-17 00:46:59
Here n.toString().split().join(',') does nothing more than n.toString().
2023-01-17 00:46:59
@tamdan I can leave just num.toString() and than loop through?
2023-01-17 00:46:59
@Konrad should I remember how big could be numbers in javascript? Sorry, I am beginner.
2023-01-17 00:46:59
The idea of the exercise is to implement addition on the individual digits with carry-over. Not to convert the array of digits into a number and back.
Answers(3) :

You can use BigInt:

const plusOne = digits => Array.from(String(BigInt(digits.join('')) + 1n), Number)

console.log(plusOne([1, 2, 3]))
console.log(plusOne([6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3]))

Comments:
2023-01-17 00:46:59
sorry for stupid question what is 1n in line ``` num += 1n``` ?
2023-01-17 00:46:59
1n is a bigint literal
2023-01-17 00:46:59
Nice solution, but not in the spirit of the exercise. Also you don't explain why the OP's code doesn't work on big numbers.
2023-01-17 00:46:59
Thank you very much to every one, I completely knew nothing about BigInt and how to work with such a big numbers in javascript, but I am going to read developer mozilla to learn about that topic.
2023-01-17 00:46:59
one more question what does Number here, because I usually saw it like Number("123") but in this code it is difficult to understand for me, sorry
2023-01-17 00:46:59
Number is the second argument passed to function Array.from() to convert each element in the array to number

This is probably what was meant to be done in the exercise

function plusOne(digits) {
  const copy = [...digits]
  for (let i = copy.length - 1; i >= 0; i -= 1) {
    if (copy[i] < 9) {
      copy[i] += 1
      for (let j = i + 1; j < copy.length; j += 1) {
        copy[j] = 0
      }
      return copy
    }
  }
  return [1, ...'0'.repeat(copy.length)]
}

console.log(plusOne([6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]).join(''))
console.log(plusOne([6,1,4,5,3,9,0,1,9,5,1,8,6,7,9,9,9,9,9]).join(''))
console.log(plusOne([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]).join(''))

The problem is with the way you are converting the number back to an array. Your code is using the split() method, which expects a separator as the argument, but you are passing an empty string. This causes the method to split the number into an array of characters, rather than numbers.

You should use the map() method instead, like this:

let incrementedArr = Array.from(num.toString()).map(Number);

This will convert the number back to a string, and then use the map() method to convert each character back to a number.

Another issue is with the way you are incrementing the number. You are incrementing the number after converting the array to a number. Instead of that you should use the last element of the array and increment it by 1 and use the rest of the array as it is.

let incrementedArr = digits.slice()
incrementedArr[incrementedArr.length-1] += 1

Also, you can use spread operator to return the incremented number.

return [...incrementedArr];

Here is the final code:

var plusOne = function(digits) {
  let incrementedArr = digits.slice()
  incrementedArr[incrementedArr.length-1] += 1
  return [...incrementedArr];
};

I hope this helps!