Skip to main content
Code Review

Return to Answer

Commonmark migration
Source Link

##Bug

Bug

##To number?

To number?

##BigInt

BigInt

##Carry

Carry

##Performance

Performance

##NOTES

NOTES

##Bug

##To number?

##BigInt

##Carry

##Performance

##NOTES

Bug

To number?

BigInt

Carry

Performance

NOTES

Source Link
Blindman67
  • 22.9k
  • 2
  • 16
  • 40

##Bug

Unfortunately both your functions return bad results for many input arguments. You don't carry.

Both should return [0,1] however they return [0]

addTwoNumbers([1], [9]); // >> [0] wrong
addTwoNumbers2([1], [9]); // >> [0] wrong

And the return for the following should be [6,0,1] but they return [6,6]

addTwoNumbers([9], [7, 9]); // >> [6, 6] wrong
addTwoNumbers2([9], [7, 9]); // >> [6, 6] wrong

The reason is that you forget to deal with the carry.

##To number?

Konijn's answer is a tempting solution but will also fail as it is limited by JS Number.

addTwoNumbers([1,1,9,9,0,4,7,4,5,2,9,9,1,7,0,0,9], [1,9,9,0,4,7,4,5,2,9,9,1,7,0,0,9])

The correct answer is

[2,0,9,0,5,1,2,0,8,1,9,1,9,7,0,9,9]

However Konijn's solution incorrectly returns.

[0,0,9,0,5,1,2,0,8,1,9,1,9,7,0,9,9]

This is because the second number is Number.MAX_SAFE_INTEGER above which you can not get a reliable result.

##BigInt

You could use a BigInt as its size is not limited.

Big ints can be written with the suffix n

 const big = 9907919180215090099079191802150900n; // Note the suffix n

To convert the reversed number to a big int

 const a = [0,0,9,0,5,1,2,0,8,1,9,1,9,7,0,9,9,0,0,9,0,5,1,2,0,8,1,9,1,9,7,0,9,9];
 const big = BigInt(a.reverse().join(""));

Thus your function would be

 const addTwoNumbers = (a, b) => (
 BigInt(a.reverse().join("")) + 
 BigInt(b.reverse().join(""))
 ).toString().split("").reverse();

But that takes the puz out of puzzle me thinks.

##Carry

The aim is to carry the remainder of each addition onto the next digit. This is fundamental to all ALU (Arithmetic Logic Units) that are part of almost every modern CPU. (In the case of binary the carry is 1 or 0)

So when you add two values 9 + 9 the result is 8 and carry 1. You then add the 1 to the next digit. If no digit add it to zero. The result is 18.

The function is thus

Example A

function addNumbers(a, b) {
 const sum = [];
 var i = 0, carry = 0;
 while (i < a.length || i < b.length || carry > 0) {
 carry += (a[i] ? a[i] : 0) + (b[i] ? b[i] : 0);
 sum.push(carry % 10);
 carry = carry / 10 | 0;
 i++;
 }
 return sum;
}

Note That it continues adding digits until the carry is zero.

##Performance

I am not surprised that the big int solution is nearly 7 times slower than carry method (example A) above, but this is due to the reverses, joins, and split

Big int are not fast (Very slow compared to standard JS numbers), doing the same sum on big int literals is only 5 times faster than the carry method (example A)

##NOTES

BigInt is very new and you should check the browser for support before using it.

Big int also sees the arrival of 64bit int arrays (YAY YAY YAY) BigUint64Array, BigInt64Array (sorry MDN has empty pages on these references)

lang-js

AltStyle によって変換されたページ (->オリジナル) /