Sum of Two Integers
Add without + or − operators — XOR for sum bits, AND+shift for carry, loop until carry clears.
intermediate3 min read
- dsa
- bit
- interview
- Meta
- Amazon
The problem
Given integers a and b, return their sum without using the + or - operators.
Input: a = 1, b = 2
Output: 3
Input: a = 2, b = 3
Output: 5
Brute force (not bit math)
Loop increment — banned in spirit, and awkward for negatives.
Optimal: XOR + carry
a ^ b— sum without carry(a & b) << 1— carry bits- Repeat until carry is 0
In languages with fixed 32-bit ints this is natural. JS numbers are IEEE doubles but bitwise ops use 32-bit signed integers — so mask with >>> 0 carefully for unsigned interpretation, and for LC-style 32-bit:
function getSum(a: number, b: number): number {
while (b !== 0) {
const carry = (a & b) << 1;
a = a ^ b;
b = carry;
}
return a;
}
| Time | O(1) — bounded by bit width (≤ 32 iterations) |
| Space | O(1) |
Why it works
Half-adder logic: sum bit is XOR, carry is AND shifted. Full addition is ripple of that.
Recursive form
function getSumRec(a: number, b: number): number {
if (b === 0) return a;
return getSumRec(a ^ b, (a & b) << 1);
}
Edge cases
- Negatives — two’s complement; JS 32-bit ops handle them if you stay in 32-bit land
b = 0early exit- Overflow beyond 32-bit — problem usually fits 32-bit
a = -1, b = 1→ 0
Common bugs
- Using
+accidentally in helpers - Infinite loop if carry shift not applied
- Confusing JS
>>>vs<<on sign bit (still works for standard LC tests with the loop above)
Interview delivery
- No +/− → bit ops.
- XOR sum, AND carry.
- Loop.
- Trace 2+3:
- 10 ^ 11 = 01, carry 100
- 01 ^ 100 = 101, carry 0 → 5
- Mention half-adder.
Related
Full trace a=5 (101), b=3 (011)
- carry = (101 & 011)<<1 = 010<<1 = 100; a = 101^011 = 110; b = 100
- carry = (110 & 100)<<1 = 100<<1 = 1000; a = 010; b = 1000
- carry = 0; a = 010^1000 = 1010 → 10
Negatives in two’s complement
Bitwise algorithms still work on fixed-width two’s complement addition. JS bitwise ops convert to Int32. LC constraints keep results in 32-bit range; you usually don’t need BigInt.
What not to do
evalhacks- Array of length a filled and length b — only works for non-negatives and wastes memory
- Log/exp tricks — precision landmines
Bit addition is the point of the problem.