题目
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
解体思路
首先明确要求:在此题当中,我们不能使用乘法、除法和取模操作。所以,我们只能够使用加法、减法和位操作。
先看一个例子。
假设我们要进行15除以3这个操作,那么15就是被除数,3是除数。除法简单地来说就是计算除数能够从被除数当中减去多少次(知道被除数不能再减,不然就成了负数)。
首先15 - 3 = 12,12 > 0。然后我们可以尝试减去更多,将3向左移一位,我们得到3 << 1 = 6。15 - 6 = 9,9仍然大于0。我们再次移位,3 << 2 = 12,15 - 12 = 3。然后再次移位,3 << 3 = 24,15 - 24 < 0。这时候我们知道最多只能将3向左移位两次,不然被除数就会为负。
我们知道12是由3向左移位两次得到,12是3的4倍。4 = 1 << 2。12 = (1 << 2)*3。于是可以将4加入到结果当中(初始结果为0)。以上过程类似与15 = 3 * 4 + 3,我们得到了系数4和余数3。
然后我们继续以上的过程。对余数3进行上面的操作,我们得到了0。最后结果为result = (1 << 2) + (1 << 0)。
注意,有两种情况会引起溢出:
1. divisor = 0
2. dividend = INT_MAX 并且 divisor = -1,因为abs(INT_MIN) = INT_MAX + 1
代码如下:
class Solution {
public:
int divide(int dividend, int divisor) {
int result = 0;
if (divisor == 0)
{
return INT_MAX;
}
if (dividend == INT_MIN && divisor == -1)
{
return INT_MAX;
}
if (dividend == 0)
{
return 0;
}
int sign;
if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0))
{
sign = 0;
}
else{
sign = 1;
}
long long did = labs(dividend); //注意这里应该是labs,不要使用abs
long long dis = labs(divisor);
long long temp = dis;
int count = 0;
while (temp <= did)
{
temp = temp << 1;
count++;
}
count--;
while (did > 0)
{
if (did < dis) //被除数已经除尽,余数为0或者小于除数
{
break;
}
if (did - (dis << count) < 0 && count > 0)
{
count--;
continue;
}
did = did - (dis << count);
result = result + (1 << count);
count--;
}
if (sign)
{
return -result;
}
else{
return result;
}
}
};