Subtract Two Numbers Without Using Arithematic Operators
Problem
Given two integers x and y, compute x - y without using the arithmetic subtraction operator (-). Use bitwise operators and shifts only, and preserve two's-complement semantics for negative numbers.
Examples
Example 1
Input: x = 10, y = 4
Output: 6
Example 2
Input: x = 5, y = -3
Output: 8
Solution
This problem is a small variant of the addition-without-+ trick (LeetCode 371). Subtraction can be reduced to addition by using two's complement: x - y == x + (-y) where -y == ~y + 1.
We present two concise approaches: (A) use an add routine that uses XOR/AND+shift to compute sum+carry iteratively, then compute x + (~y + 1), and (B) directly perform the iterative subtraction-like step using XOR and borrow propagation.

Method 1 — Two's-complement reduction (use add)
Intuition
In two's-complement arithmetic, negation is ~y + 1. So subtraction x - y equals x + (~y + 1). Implement add(a, b) using bitwise XOR for sum and bitwise AND/shift for carry, and reuse it for subtraction.
Approach
- Implement
add(a, b):sum = a ^ b(sum without carries).carry = (a & b) << 1(carries shifted into place).- Repeat with
a = sum,b = carryuntilb == 0.
- Compute
neg_y = add(~y, 1)and returnadd(x, neg_y).
Edge cases: work in fixed-width words (32/64-bit) depending on language; be aware of overflow behavior according to language semantics.
Code
C++
class Solution {
public:
static int add(int a, int b) {
while (b != 0) {
int sum = a ^ b;
int carry = (a & b) << 1;
a = sum;
b = carry;
}
return a;
}
static int subtract(int x, int y) {
int neg_y = add(~y, 1);
return add(x, neg_y);
}
};
Go
package main
func Add(a, b int32) int32 {
for b != 0 {
sum := a ^ b
carry := (a & b) << 1
a = sum
b = carry
}
return a
}
func Subtract(x, y int32) int32 {
negY := Add(^y, 1)
return Add(x, negY)
}
Java
class Solution {
public static int add(int a, int b) {
while (b != 0) {
int sum = a ^ b;
int carry = (a & b) << 1;
a = sum;
b = carry;
}
return a;
}
public static int subtract(int x, int y) {
int negY = add(~y, 1);
return add(x, negY);
}
}
Python
class Solution:
@staticmethod
def add(a: int, b: int) -> int:
while b != 0:
s = a ^ b
carry = (a & b) << 1
a = s
b = carry
return a
@staticmethod
def subtract(x: int, y: int) -> int:
neg_y = Solution.add(~y, 1)
return Solution.add(x, neg_y)
Complexity
- ⏰ Time complexity:
O(k)wherekis the machine-word bit-width (each iteration propagates carries/borrows across bits). - 🧺 Space complexity:
O(1)extra space.
Method 2 — Direct XOR/borrow iteration (no explicit add)
Intuition
This method uses the same idea as addition without + but propagates borrows instead of carries. The recurrence x' = x ^ y, y' = (~x & y) << 1 repeatedly removes borrow bits until y == 0 and x contains the result.
Approach
- While
y != 0do:diff = x ^ y(subtraction without borrows applied yet).borrow = (~x & y) << 1(bits that must be borrowed).- Set
x = diff,y = borrow.
- When
y == 0,xis the final result.
This loop is equivalent to recursive sub(x ^ y, (~x & y) << 1) and terminates in O(k) steps.
Code
C++
class Solution {
public:
static int subtract(int x, int y) {
while (y != 0) {
int diff = x ^ y;
int borrow = (~x & y) << 1;
x = diff;
y = borrow;
}
return x;
}
};
Go
package main
func Subtract(x, y int32) int32 {
for y != 0 {
diff := x ^ y
borrow := (^x & y) << 1
x = diff
y = borrow
}
return x
}
Java
class Solution {
public static int subtract(int x, int y) {
while (y != 0) {
int diff = x ^ y;
int borrow = (~x & y) << 1;
x = diff;
y = borrow;
}
return x;
}
}
Python
class Solution:
@staticmethod
def subtract(x: int, y: int) -> int:
while y != 0:
diff = x ^ y
borrow = (~x & y) << 1
x = diff
y = borrow
return x
Complexity
- ⏰ Time complexity:
O(k)wherekis the machine-word bit-width. - 🧺 Space complexity:
O(1)extra space.
Notes
- For languages with unbounded integers (Python) the same code works and semantics match mathematical integers; for fixed-width languages be mindful of overflow and signed shifts.