The O(n) Club: Divide Two Integers (Without /, *, or %? Madness!)
⚡ TL;DR
Dividing integers in Java when division, multiplication, and modulo are forbidden? Yep, just another day in whiteboard purgatory.
The brute-force way: subtract the divisor until only dust remains. But you’ll hit performance rock bottom pretty fast. Enter The Shift: use bitwise left shifts to speedrun subtraction and make interviewers think you do algorithmic CrossFit.// Naive, pure brute force (only for toy numbers): int divide(int dividend, int divisor) { int result = 0; int sign = ((dividend >= 0) == (divisor >= 0)) ? 1 : -1; int a = Math.abs(dividend); int b = Math.abs(divisor); while (a >= b) { a -= b; result++; } return sign * result; }
🧠 How Devs Usually Mess This Up
Everyone’s first guess is: “Why not just use Math.abs(), keep subtracting, and throw in some sign math at the end?” But then you realize Integer.MIN_VALUE laughs in the face of Math.abs() and can’t be used as a positive integer (because two’s complement is a special kind of rude). And don’t forget the charming edge case where -2<sup>31</sup> / -1 explodes right past 32-bit max value, which Java does NOT graciously wrap for you. Who knew division needed so many caveats?
🔍 What’s Actually Going On
This is making change with big bills, not pennies. Instead of shrinking your dividend one divisor at a time (AKA, retirement-level slow), you double the divisor (using left shift, AKA bit-manipulation jazz hands) until it almost overshoots the remaining dividend. Then you subtract that chunk, add the matching number of “bills” to your result, and repeat. Oh, and it’s safer to work with negatives due to how two’s complement integers play with overflow. You’re welcome.
🛠️ PseudoCode
- Special Cases: If
divisor == 0, throw. Ifdividend == Integer.MIN_VALUE && divisor == -1, returnInteger.MAX_VALUE(not today, overflow!). - Determine Sign: Result is positive if both inputs share a sign, else negative. Count negatives for fun.
- Negativize Inputs: Convert both dividend and divisor to negatives—so that we can safely live in two’s complement land without imploding
Integer.MIN_VALUE. - Bit-Shift Fiesta: While dividend ≤ divisor:
- Start with tempDivisor = divisor, multiple = 1
- Double tempDivisor (left shift) until next double would shoot past dividend or overflow
- Subtract tempDivisor from dividend and add multiple to quotient
- Sign Wrap: If the negatives count is 1, result is negative; else positive. Return your signed result and brag to your interviewer.
// Pseudocode (in that Chandler voice):
if (divisor == 0) blah();
if (dividend == INT_MIN && divisor == -1) return INT_MAX;
negCount = 2;
a = dividend; b = divisor;
if (a > 0) { a = -a; negCount--; }
if (b > 0) { b = -b; negCount--; }
res = 0;
while (a <= b) {
temp = b; mult = 1;
while (a - (temp << 1) <= 0 && temp >= (INT_MIN >> 1)) {
temp <<= 1;
mult <<= 1;
}
a -= temp;
res += mult;
}
return (negCount == 1) ? -res : res;
💻 The Code
public int divide(int dividend, int divisor) {
if (divisor == 0) throw new ArithmeticException("Divide by zero");
if (dividend == Integer.MIN_VALUE && divisor == -1) return Integer.MAX_VALUE;
int negatives = 2;
int a = dividend, b = divisor;
if (a > 0) { a = -a; negatives--; }
if (b > 0) { b = -b; negatives--; }
int result = 0;
while (a <= b) {
int temp = b, mult = 1;
while (a - (temp << 1) <= 0 && temp >= (Integer.MIN_VALUE >> 1)) {
temp <<= 1;
mult <<= 1;
}
a -= temp;
result += mult;
}
return (negatives == 1) ? -result : result;
}
⚠️ Pitfalls, Traps & Runtime Smacks
- Integer.MIN_VALUE vs -1: You WILL overflow without the guard clause. Cap it at Integer.MAX_VALUE or enjoy the fireworks.
- Zero divisor: Java will happily throw, but you should, too—preferably with flair.
- Left shifting negatives: Careful, left-shifting too far explodes values back into positive space and everything goes sideways. Always check for shifting past
Integer.MIN_VALUE >> 1. - Do NOT try to use Math.abs(Integer.MIN_VALUE): Unless you’re collecting NaN trophies.
- Time: O(log(|dividend/divisor|)). Space: O(1). Your CPU might finally get a coffee break.
🧠 Interviewer Brain-Tattoo
Fastest way to show you get bit manipulation? Solve division using shifts. Fastest way to show you don’t? Use / and say “Trust me, this scales.”