Problem
Add two integers — which may be positive or negative — without using the +
or - operators.
Signal
"Add without +" means simulating addition the way hardware does it: XOR
gives you the sum of each bit position ignoring carries, AND-then-shift gives
you exactly the carries, and you repeat until there's no carry left to add.
Approach
At the bit level, a ^ b is the sum of a and b with every carry dropped,
and (a & b) << 1 is exactly those dropped carries, shifted into position.
So: compute both, then treat the carry as a new number to add to the
XOR-sum, and repeat until the carry is 0. In C or Java, fixed-width integers
make this loop terminate naturally. Python integers don't wrap at 32 bits —
they're arbitrary precision — so a negative carry-free sum can loop forever
or come out with extra high bits set. The fix is to mask every intermediate
value to 32 bits with & 0xFFFFFFFF, and at the very end, detect whether the
32-bit result "looks negative" (its top bit is set, i.e. it's greater than
0x7FFFFFFF) and convert it back into a genuine negative Python int via
two's-complement inversion.
Skeleton
mask = 0xFFFFFFFF
while b & mask:
carry = (a & b) << 1
a = (a ^ b) & mask
b = carry & mask
return a if a <= 0x7FFFFFFF else ~(a ^ mask)
Solution
def get_sum(a: int, b: int) -> int:
mask = 0xFFFFFFFF
while b & mask:
carry = (a & b) << 1
a = (a ^ b) & mask
b = carry & mask
return a if a <= 0x7FFFFFFF else ~(a ^ mask)
Complexity
O(1) time — at most 32 iterations, one per bit position. O(1) space.
Pitfalls
- This is the whole difficulty of the problem in Python: porting the
bit-trick directly from C/Java without masking gives wrong answers or an
infinite loop, because Python's
intnever overflows or wraps —b & maskis what makes the loop actually terminate, and the finala <= 0x7FFFFFFFcheck plus~(a ^ mask)is what turns a 32-bit two's-complement bit pattern back into a real negative Python integer. - Masking
abut forgetting to maskb(the carry) leaves stray high bits that make thewhile b & maskloop condition wrong. - Testing only positive inputs hides this entire class of bug — always trace through at least one negative operand by hand before trusting the solution.