题目:Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
分析:这道题最基本的想法是进行减法,dividend-divisor,每一次成功减去之后divisor加倍(左移一位),如果不能减,并且divisor是加倍之后的,那么divisor折半(右移一位)。
对正负数的处理:一开始的想法是把dividend和divisor都放到正数空间来进行运算,发现无法处理INT_MIN。int表示的范围是[-2147483648, 2147483647],INT_MIN=-2147483648,INT_MAX=2147483647,abs(INT_MIN)=-INT_MIN=INT_MIN。意味着你必须将dividend和divisor转化到负数空间进行运算。
第26行所处理的情况开始没有想到:(例如2147483647 / 2)在这种情况下,if (dividend < divisor)的条件满足,divisor << 1后有可能溢出,使得结果错误。之前有遇到过对一个数先右移操作>>,再左移操作<<,右移操作使得数字变为0,无法左移操作<<来恢复。
#include <climits>
#include <cmath>
#include <iostream>
using namespace std;
class Solution {
public:
int divide(int dividend, int divisor) {
if (divisor == 0) return INT_MAX;
if (dividend == INT_MIN) {
if (divisor == 1) return INT_MIN;
if (divisor == -1) return INT_MAX;
}
int res = 0, multiper = 1;
bool minus = false;
if ((dividend > 0 && divisor < 0) ||
(dividend < 0 && divisor > 0)){
minus = true;
}
if (dividend != INT_MIN) { dividend = -abs(dividend); }
if (divisor != INT_MIN) { divisor = -abs(divisor); }
while (dividend < 0) {
if (dividend < divisor) {
dividend -= divisor;
res += multiper;
if ((divisor << 1) > 0) continue; //error prone
divisor <<= 1;
multiper <<= 1;
} else if (dividend == divisor) {
res += multiper;
break;
} else {
if (multiper == 1) { break; }
multiper >>= 1;
divisor >>= 1;
}
}
return minus ? -res : res;
}
};
周末水博客系列>.<