🧠
Recursive Bitwise Sum Using XOR and AND
💡 This approach uses recursion instead of iteration to add two integers using bitwise operations, illustrating the same logic in a different style.
Intuition
Sum bits are XOR of a and b, carry bits are AND shifted left; recursively add sum and carry until carry is zero.
Algorithm
- If b is zero, return a as the sum.
- Calculate sum as XOR of a and b.
- Calculate carry as AND of a and b, shifted left by 1.
- Recursively call the function with sum and carry.
💡 The recursion naturally handles carry propagation until no carry remains.
def getSum(a: int, b: int) -> int:
MASK = 0xFFFFFFFF
if b == 0:
return a if a <= 0x7FFFFFFF else ~(a ^ MASK)
sum_ = (a ^ b) & MASK
carry = ((a & b) << 1) & MASK
return getSum(sum_, carry)
# Driver code
if __name__ == "__main__":
print(getSum(1, 2)) # Output: 3
print(getSum(-2, 3)) # Output: 1
Line Notes
MASK = 0xFFFFFFFFMasks to 32 bits to simulate 32-bit integer overflow
if b == 0:Base case: no carry means addition is complete
return a if a <= 0x7FFFFFFF else ~(a ^ MASK)Convert unsigned to signed integer
sum_ = (a ^ b) & MASKCalculate sum bits without carry
carry = ((a & b) << 1) & MASKCalculate carry bits shifted left
return getSum(sum_, carry)Recursive call with new sum and carry
public class Solution {
public int getSum(int a, int b) {
if (b == 0) {
if ((a & 0x80000000) != 0) {
a = ~((~a) & 0xFFFFFFFF);
}
return a;
}
int sum = (a ^ b);
int carry = (a & b) << 1;
return getSum(sum, carry);
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.getSum(1, 2)); // Output: 3
System.out.println(sol.getSum(-2, 3)); // Output: 1
System.out.println(sol.getSum(2147483647, 1)); // Output: -2147483648
}
}
Line Notes
if (b == 0) {Base case: no carry means addition complete
if ((a & 0x80000000) != 0) {Check if sign bit is set (negative number)
a = ~((~a) & 0xFFFFFFFF);Convert from unsigned to signed 32-bit integer
return a;Return final sum
int sum = (a ^ b);Sum bits without carry using XOR
int carry = (a & b) << 1;Carry bits shifted left
return getSum(sum, carry);Recursive call with updated values
#include <iostream>
using namespace std;
class Solution {
public:
int getSum(int a, int b) {
if (b == 0) {
if ((a & 0x80000000) != 0) {
a = ~((~a) & 0xFFFFFFFF);
}
return a;
}
int sum = a ^ b;
int carry = (a & b) << 1;
return getSum(sum, carry);
}
};
int main() {
Solution sol;
cout << sol.getSum(1, 2) << endl; // Output: 3
cout << sol.getSum(-2, 3) << endl; // Output: 1
cout << sol.getSum(2147483647, 1) << endl; // Output: -2147483648
return 0;
}
Line Notes
if (b == 0) {Base case for recursion
if ((a & 0x80000000) != 0) {Check if sign bit is set (negative number)
a = ~((~a) & 0xFFFFFFFF);Convert from unsigned to signed 32-bit integer
return a;Return final sum
int sum = a ^ b;Sum bits without carry
int carry = (a & b) << 1;Carry bits shifted left
return getSum(sum, carry);Recursive call to continue addition
var getSum = function(a, b) {
const MASK = 0xFFFFFFFF;
if (b === 0) {
return (a & 0x80000000) ? ~( (a ^ MASK) ) : a;
}
let sum = (a ^ b) & MASK;
let carry = ((a & b) << 1) & MASK;
return getSum(sum, carry);
};
// Test
console.log(getSum(1, 2)); // Output: 3
console.log(getSum(-2, 3)); // Output: 1
console.log(getSum(2147483647, 1)); // Output: -2147483648
Line Notes
const MASK = 0xFFFFFFFF;Mask to simulate 32-bit integer overflow
if (b === 0) {Base case: no carry means addition done
return (a & 0x80000000) ? ~( (a ^ MASK) ) : a;Convert from unsigned to signed 32-bit integer
let sum = (a ^ b) & MASK;Sum bits without carry
let carry = ((a & b) << 1) & MASK;Carry bits shifted left
return getSum(sum, carry);Recursive call to add carry
TimeO(log(max(a,b)))
SpaceO(log(max(a,b))) due to recursion stack
Each recursive call processes carry bits; max 32 calls for 32-bit integers.
💡 Recursion depth equals number of carry propagations, which is at most 32 for 32-bit integers.
Interview Verdict: Accepted but less preferred due to recursion overhead
This approach is elegant but may cause stack overflow for large inputs; iterative is preferred in interviews.