Given two integers a and b, return the sum of the two integers without using the + and - operators.
Example 1:
Input: a = 1, b = 1
Output: 2Example 2:
Input: a = 4, b = 7
Output: 11Constraints:
-1000 <= a, b <= 1000
You should aim for a solution with O(1) time and O(1) space.
A brute force approach would use the addition operator. Can you think of a way to perform addition without using it? Maybe you should consider solving this using bit manipulation.
We can use the bitwise XOR operator to perform addition. If both a and b have 1 at the same bit position, the sum at that position is 0, and a carry of 1 is generated. If the bits are different, the sum at that position is 1. Additionally, we account for the carry from the previous step in the next iteration.
We iterate bit by bit from 0 to 31 since the given integers are 32-bit. We track the carry, initially set to 0, and initialize the result as res. During iteration, the XOR of the bits at the i-th position of both integers and the carry determines the current bit of res. How can you handle negative numbers?
To handle negative numbers, if the final result exceeds the maximum positive 32-bit integer, it means the number should be negative. We adjust it using bitwise operations: flipping the bits with res ^ ((2 ^ 32) - 1) and applying ~ to restore the correct two’s complement representation. This ensures the result correctly represents signed 32-bit integers.
Before attempting this problem, you should be comfortable with:
The goal is to compute the sum of two integers.
In the brute force approach, we rely directly on the language’s built-in arithmetic addition operator. This is the most straightforward and intuitive solution because:
This approach focuses purely on correctness and simplicity, without worrying about implementation details.
a and b.a + b.The problem asks us to compute the sum of two integers without using the + or - operators.
At the bit level, addition works using two simple ideas:
^) gives the sum of two bits without considering carry&) + left shift determines where a carry is generatedFor example (single bit):
0 + 0 → sum = 0, carry = 01 + 0 → sum = 1, carry = 01 + 1 → sum = 0, carry = 1By repeating this logic for all bit positions, we can simulate normal addition exactly as it happens in hardware.
Because integers are stored in fixed-width (32-bit) two's complement form, we also need to:
result to store the final sumcarry = 0mask to keep numbers within 32 bits0 to 31:i-th bit from both numberssum_bit = a_bit XOR b_bit XOR carrycarry:carry = (a_bit + b_bit + carry) ≥ 2i-th bit in the result if sum_bit is 1result represents a negative number in 32-bit two's complement:resultclass Solution:
def getSum(self, a: int, b: int) -> int:
carry = 0
res = 0
mask = 0xFFFFFFFF
for i in range(32):
a_bit = (a >> i) & 1
b_bit = (b >> i) & 1
cur_bit = a_bit ^ b_bit ^ carry
carry = (a_bit + b_bit + carry) >= 2
if cur_bit:
res |= (1 << i)
if res > 0x7FFFFFFF:
res = ~(res ^ mask)
return resWe need to add two integers without using + or -.
Binary addition can be built from two operations:
Sum without carry
a XOR b gives the bit-by-bit sum ignoring carry1 XOR 1 = 0, which matches sum without carry)Carry information
a AND b tells us where both bits are 1, which creates a carry<< 1) moves that carry to the next higher bitSo we can repeatedly:
carrycarry again (by setting b = carry)We keep doing this until there is no carry left (b == 0).
Because many languages use fixed-width integers (like 32-bit signed integers), we use a mask to keep only the lower 32 bits at each step. Finally, if the result represents a negative number in 32-bit two's complement form, we convert it back to a signed integer.
mask to keep only 32 bitsmax_int as the largest 32-bit signed integerb is not zero:carry:carry = (a AND b) << 1carry:a = (a XOR b), then apply the 32-bit maskcarry into b (also masked to 32 bits)a holds the 32-bit result.a is within signed range, return it directly.When using bit manipulation to add integers, negative numbers are represented in two's complement form. In languages like Python that have arbitrary-precision integers, you must explicitly mask results to 32 bits and convert back to signed representation when the result exceeds 0x7FFFFFFF. Failing to do this will produce incorrect results for negative inputs or negative sums.
In languages with fixed-width integers (like Java, C++), left-shifting a negative carry can cause issues. When b becomes negative and you compute (a & b) << 1, the carry propagates correctly due to two's complement representation. However, in Python without masking, the carry can grow indefinitely, causing an infinite loop. Always apply a 32-bit mask to both a and b in each iteration.
A common mistake is mixing up the roles of XOR and AND in the addition algorithm. XOR (^) computes the sum without carry, while AND (&) followed by left shift computes the carry. Swapping these operations or forgetting the left shift on the carry will produce wrong results. Remember: XOR gives you what stays, AND shifted gives you what carries over.