371. Sum of Two Integers
Description
Calculate the sum of two integers a and b, but you are not allowed to use the operator +
and -
.
Example 1:
Input: a = 1, b = 2 Output: 3
Example 2:
Input: a = -2, b = 3 Output: 1
My Solution
Source Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
let getSum = function (a, b) {
//keep left shifting until there are no more digit sums to carry
while (a != 0) {
//carries occur at positions where both bits are 1
let carryDigits = a & b;
//'add' together bits
b = a ^ b;
//actually 'carry over' the carry digits by shifting left
a = carryDigits << 1;
}
return b;
};
Analysis
This was actually kind of difficult despite it being marked as an easy problem. I feel like I had a vague idea about how to go about this one only because of a similar problem I had to do back in college. If I had never done that problem I don't think I could have come up with a solution for this.
I tried an example with 11
and 3
so I could think
about how to 'transform' the summands into what their sum should be.
1011 + 0011 = 1110
If we start to add the two number together like you normally would,
we would start with the rightmost bits and do 1+1=10
.
Another way to think about it is 1+1=0
and we have to
carry the 1
. How would we actually carry that 1
?
We just shift it left just like if you were calculating the sum by hand.
1 + 1 = (carry 1)0 = 10
So how do we know which bits will result in a carry? If we look at the example again it's easy to see we will need to do carrying for the 3rd and 4th bits.
1011 + 0011 = 10(carry 1 + (1+1))0 = 1(carry 1)10 = 1110
When both bits to be summed are 1
it will result in a carry.
We could use &
the bitwise AND operation to locate these bits.
1011 & 0011 = 0011Then to actually 'do' the carrying, we simply shift the bits left.
0011 << 1 = 0110
But this isn't exactly what we want. It's close but not quite.
The leftmost digit is still wrong. If we think about how we add
the bits by hand again, we notice that 1+0=1
and
1+1=(carry 1)0
. This looks similar to a bitwise operation,
in particular bitwise XOR ^
.
1011 ^ 0011 = 1000The first leftmost bit is correct but the second two aren't. We will need to combine XOR and AND and shifting to get the result we want.
So to summarize this so far since I'm really bad at explaining things,
when we add two bits together they result in either 1
or
0
without needing to carry or 0
and
needing to carry. When at least one bit is 0
,
there will be no carry and we can compute that sum by using
^
XOR. To locate the bits where carrying occurs,
we can use &
AND. To actually 'do' the carrying,
we <<
shift the bits left by 1 position.
So for the example of 11
and 3
,
1011 & 0011 = 0011 0011 << 1 = 0110 1011 ^ 0011 = 1000
So what do we do with these resulting numbers? We add them again. Why? We are adding the result of adding the numbers together without carrying and the results of just carrying.
0110 & 1000 = 0000 0000 << 1 = 0000 0110 ^ 1000 = 1110
There are no bits left to carry so we're done. Also observe that we got the right answer, 14.