Taro Logo

Divide Two Integers

Medium
Apple logo
Apple
1 view
Topics:
Bit Manipulation

Given two integers dividend and divisor, divide the dividend by the divisor without using multiplication, division, or the modulo operator. The division should truncate towards zero.

Assume we are working in an environment that can only store integers within the 32-bit signed integer range: [-2^31, 2^31 - 1]. If the quotient is strictly greater than 2^31 - 1, return 2^31 - 1. If the quotient is strictly less than -2^31, return -2^31.

For example:

divide(10, 3) == 3
divide(7, -3) == -2

Could you implement this integer division without using multiplication, division, or the modulo operator?

Solution


Naive Solution

A simple approach is to repeatedly subtract the divisor from the dividend until the dividend becomes smaller than the divisor. The number of subtractions will be the quotient.

Edge Cases:

  • Divisor is 0: This should throw an error as division by zero is undefined.
  • Dividend is 0: The quotient is 0.
  • Signs: Handle the signs of the dividend and divisor to determine the sign of the quotient.
  • Overflow: Check for potential overflow issues if the quotient is too large or too small.

Code (Python):

def divide_naive(dividend, divisor):
    if divisor == 0:
        raise ZeroDivisionError("Cannot divide by zero")

    sign = -1 if (dividend < 0) ^ (divisor < 0) else 1
    dividend = abs(dividend)
    divisor = abs(divisor)

    quotient = 0
    while dividend >= divisor:
        dividend -= divisor
        quotient += 1

    quotient *= sign

    # Handle overflow
    INT_MAX = 2**31 - 1
    INT_MIN = -2**31
    if quotient > INT_MAX:
        return INT_MAX
    elif quotient < INT_MIN:
        return INT_MIN
    else:
        return quotient

Time Complexity: O(dividend / divisor). In the worst case, if the dividend is very large and the divisor is 1, this can be very slow.

Space Complexity: O(1). Constant space is used.

Optimal Solution (Bit Manipulation)

A much more efficient approach involves using bit manipulation. The idea is to use repeated subtraction, but instead of subtracting the divisor one at a time, we subtract multiples of the divisor (powers of 2 times the divisor).

  1. Determine the sign of the result.
  2. Take the absolute values of the dividend and divisor.
  3. Repeatedly subtract left-shifted versions of the divisor from the dividend.
  4. Keep track of how many times each shifted divisor can be subtracted.
  5. Handle overflow.

Edge Cases:

  • Divisor is 0: Throw an error.
  • Dividend is 0: Return 0.
  • Signs: Handle signs correctly.
  • Overflow: Properly handle integer overflow by clamping the result to the maximum or minimum integer value.

Code (Python):

def divide(dividend, divisor):
    if divisor == 0:
        raise ZeroDivisionError("Cannot divide by zero")

    sign = -1 if (dividend < 0) ^ (divisor < 0) else 1
    dividend = abs(dividend)
    divisor = abs(divisor)

    quotient = 0
    while dividend >= divisor:
        temp = divisor
        multiple = 1
        while dividend >= (temp << 1):
            if temp > 2**30: # avoid left shift overflow
                break
            temp <<= 1
            multiple <<= 1
        dividend -= temp
        quotient += multiple

    quotient *= sign

    INT_MAX = 2**31 - 1
    INT_MIN = -2**31
    if quotient > INT_MAX:
        return INT_MAX
    elif quotient < INT_MIN:
        return INT_MIN
    else:
        return quotient

Time Complexity: O(log(dividend)). This is because, in each iteration, we are essentially halving the dividend.

Space Complexity: O(1). Constant space is used.