Adding two numbers without + or - comes down to how computers perform addition at the hardware level: with bitwise operations.
When you add two binary digits, you produce a sum bit (XOR) and a carry bit (AND, shifted left). A CPU's adder circuit repeats this until no carry remains. The task is to replicate that logic in code. Addition is a bitwise operation underneath, and the + operator is an abstraction over XOR and AND.
-1000 <= a, b <= 1000 → Values fit comfortably in a 32-bit signed integer, and the result range (-2000 to 2000) never overflows. This rules out worrying about the result, but the carry shifts still touch the sign bit, which matters for the language details below.+ and - → The only arithmetic available is bitwise: AND, OR, XOR, shift, NOT.If you can't add directly, count up or down one step at a time. To compute a + b, start at a and move b steps toward the result. Each step increments or decrements by 1 using only bitwise operators.
A single increment without + comes from the identity -~x == x + 1. The bitwise complement ~x equals -x - 1 in two's complement, so negating it gives x + 1. By the same reasoning, ~-x == x - 1.
This is slow, but it establishes a baseline and shows that arithmetic can be expressed entirely with bitwise operators.
b is positive, increment a by 1 exactly b times (using -~a to increment).b is negative, decrement a by 1 exactly |b| times (using ~-a to decrement).b is zero, return a directly.a.Processing one unit at a time is slow when b is large. The next approach handles all 32 bit positions at once, the way a CPU adder does, which brings the running time down to a fixed number of iterations.
Binary addition of two single bits has two outputs, a sum and a carry:
0 + 0 = 0 (sum = 0, carry = 0)0 + 1 = 1 (sum = 1, carry = 0)1 + 0 = 1 (sum = 1, carry = 0)1 + 1 = 10 (sum = 0, carry = 1)The sum column is XOR, and the carry column is AND. A carry belongs in the next higher bit position, so it is shifted left by 1.
Applied to two full numbers a and b:
a XOR b gives the sum at every bit position, ignoring carries.(a AND b) << 1 gives the carries, shifted into the positions they affect.The partial sum and the carry still need to be combined, and that combination is itself an addition. Applying the same XOR and AND-shift step to them, repeatedly, resolves it. This is how a ripple-carry adder works in hardware: each iteration moves carries one position further. With 32-bit integers, the carry runs out of room after at most 32 iterations.
Every iteration shifts the carry left by one position. The lowest set bit of the carry therefore moves strictly higher each time, so within 32 iterations the carry has nowhere left to go and becomes 0. Cascading carries, such as adding 111 + 001, take more iterations because each carry generates the next, but the leftward shift still bounds the total at the integer width.
b (the carry) is not zero:carry = (a AND b) << 1a = a XOR bb = carry for the next iterationb becomes 0, all carries have been resolved. Return a.