Night Ninjas
Night Ninjas

Reputation: 17

Javascript - adding Integers using arrays

I am using an array in order to calculate large powers of 2. The arrays add to each other and afterwords they calculate the carries and loop n-1 amount of times until i end up with the number as an array. I do this in order to avoid the 15 digit limit that JavaScript has.

Everything works fine once i reach n = 42, where the carries start to be overlooked and numbers aren't reduced, producing wrong answers.

I tried changing the method of which the carry is processed inside the while loop from basic addition to integer division and modulus Sounds stupid but i added an extra loop to check if any elements are greater than 10 but it didn't find them.

  for (var n = 1; n <= 100; n++) {
    for (var i = 0, x = [2]; i < n - 1; i++) { // Loop for amount of times to multiply
      x.unshift(0)
      for (var j = x.length - 1; j > 0; j--) { // Double each element of the array
        x[j] += x[j]
      }
      for (j = x.length - 1; x[j] > 0; j--) { // Check if element >= 10 and carry
        while (x[j] >= 10) {
          x[j - 1] += Math.floor(x[j] / 10)
          x[j] = x[j] % 10
        }
      }
      if (x[0] === 0) {
        x.shift()
      }
    }
    console.log('N: ' + n + ' Array: ' + x)
  }

The expected results are that each element in the array will be reduced into a single number and will "carry" onto the element to its left like :

N: 1 Array: 2
N: 2 Array: 4
N: 3 Array: 8
N: 4 Array: 1,6
N: 5 Array: 3,2
N: 6 Array: 6,4

but starting at n=42 carries get bugged looking like this:

N: 42 Array: 4,2,18,18,0,4,6,5,1,1,1,0,4
N: 43 Array: 8,4,36,36,0,8,12,10,2,2,2,0,8
N: 44 Array: 1,7,5,9,2,1,8,6,0,4,4,4,1,6
N: 45 Array: 2,14,10,18,4,2,16,12,0,8,8,8,3,2
N: 46 Array: 7,0,3,6,8,7,4,4,1,7,7,6,6,4
N: 47 Array: 14,0,7,3,7,4,8,8,3,5,5,3,2,8

What's the error that could be throwing it off like this?

Upvotes: 0

Views: 268

Answers (2)

mhpcc
mhpcc

Reputation: 145

If all you want are large powers of 2, why are you going through the insane hassle of using lists to calculate that? Isn't this the exact same:

function BigPow2(x, acc=2.0) {
    //document.writeln(acc);
    acc = acc >= 5 ? acc / 5 : acc * 2;
    return x <= 1 ? acc : BigPow2(x-1, acc);
}

Or alternatively, use BigInt?

Upvotes: 0

Georgy
Georgy

Reputation: 2462

I think the reason your code doesn't work is this line for (j = x.length - 1; x[j] > 0; j--) { // Check if element >= 10 and carry you don't want to check for x[j] > 0 but j > 0.

Also your second loop: for (var i = 0, x = [2]; i < n - 1; i++) { - you don't need it, there is no reason to recalculate everything on every iteration, you can use previous result.

You can also double values this way : x = x.map(n => n * 2) (seems a bit more coventional to me).

And there is no need to x[j - 1] += Math.floor(x[j] / 10) it could be just x[j - 1] += 1 as previous numbers are up to 9, doubled they are no more than 18 so 1 is the only case if x[j] >= 10.

Could be the code:

let x = [2] // starting point
for (var n = 1; n <= 100; n++) {
  x = [0, ...x].map(n => n * 2)
  for (j = x.length - 1; j > 0; j--) {
    if (x[j] >= 10) {
      x[j - 1] += 1
      x[j] %= 10
    }
  }
  if (x[0] === 0) {
    x = x.slice(1)
  }
  console.log('N: ' + n + ' Array: ' + x)
}

Upvotes: 1

Related Questions