371. Sum of Two Integers - Explanation
Description
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
Topics
Recommended Time & Space Complexity
You should aim for a solution with O(1) time and O(1) space.
Hint 1
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.
Hint 2
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.
Hint 3
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?
Hint 4
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.
Prerequisites
Before attempting this problem, you should be comfortable with:
- Bit Manipulation Basics - Understanding bitwise operators (AND, OR, XOR, NOT) and how they work at the binary level
- Two's Complement Representation - How negative numbers are represented in binary using 32-bit signed integers
- Binary Addition - Understanding how carry propagation works when adding binary numbers bit by bit
1. Brute Force
Intuition
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:
- Addition is a fundamental operation supported natively by all programming languages
- The language runtime already handles all edge cases such as:
- negative numbers
- carry propagation
- integer representation
This approach focuses purely on correctness and simplicity, without worrying about implementation details.
Algorithm
- Take the two input integers
aandb. - Use the built-in addition operation to compute
a + b. - Return the result.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Bit Manipulation
Intuition
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:
- XOR (
^) gives the sum of two bits without consideringcarry - AND (
&) + left shift determines where acarryis generated
For example (single bit):
0 + 0 → sum = 0, carry = 01 + 0 → sum = 1, carry = 01 + 1 → sum = 0, carry = 1
By 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:
- limit results to 32 bits
- correctly convert the result back if it represents a negative number
Algorithm
- Initialize:
resultto store the final sumcarry = 0- a
maskto keep numbers within 32 bits
- For each bit position from
0to31:- Extract the
i-th bit from both numbers - Compute the current sum bit using XOR:
sum_bit = a_bit XOR b_bit XOR carry - Update the
carry:carry = (a_bit + b_bit + carry) ≥ 2 - Set the
i-th bit in theresultifsum_bitis1
- Extract the
- After processing all bits:
- If the
resultrepresents a negative number in 32-bit two's complement:- Convert it back to a signed integer
- If the
- Return the
result
class 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 resTime & Space Complexity
- Time complexity:
- Space complexity:
3. Bit Manipulation (Optimal)
Intuition
We need to add two integers without using + or -.
Binary addition can be built from two operations:
Sum without
carrya XOR bgives the bit-by-bit sum ignoringcarry
(because1 XOR 1 = 0, which matches sum withoutcarry)
Carryinformationa AND btells us where both bits are1, which creates acarry- shifting left by 1 (
<< 1) moves thatcarryto the next higher bit
So we can repeatedly:
- compute the
carry - update the partial sum using XOR
- add the
carryagain (by settingb = 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.
Algorithm
- Define constants for 32-bit handling:
maskto keep only 32 bitsmax_intas the largest 32-bit signed integer
- While
bis not zero:- Compute
carry:carry = (a AND b) << 1
- Compute sum without
carry:a = (a XOR b), then apply the 32-bitmask
- Move
carryintob(also masked to 32 bits)
- Compute
- After the loop,
aholds the 32-bitresult. - If
ais within signed range, return it directly. - Otherwise, convert from unsigned 32-bit to a negative signed value and return it.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Forgetting to Handle Negative Numbers
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.
Infinite Loop with Negative Carry
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.
Confusing XOR and AND Operations
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.
Sign in to join the discussion