给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 。
注意:
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1
思路有两种:
①减法替代除法
int af = a>0?1:-1;
int bf = b>0?1:-1;
int aa = a>0?a:-a;
int ba = b>0?b:-b;
int d = 0;
while(aa>=0&&aa>=ba){
aa -= ba;
d += 1;
}
int f = af==bf?1:-1;
d = f>0?d:-d;
return d;
②位运算替代除法
int ua = abs(a);
int ub = abs(b);
for (int i = 31; i >= 0; i--) {
if ((ua >> i) >= ub) {
ua = ua - (ub << i);
res += 1 << i;
}
}
问题在于边界处理:
当a为INT_MIN时,取绝对值会越界,借鉴代码如下
class Solution {
public:
int divide(int a, int b) {
if(a == INT_MIN && b == -1)
return INT_MAX;
if(b == INT_MIN)
return a==b?1:0;
int res = 0;
//将-2^31转换为-2^31+1~0之间
if(a == INT_MIN){
a -= -abs(b);
res += 1;
}
int sign = (a > 0) ^ (b > 0) ? -1 : 1;
int ua = abs(a);
int ub = abs(b);
for (int i = 31; i >= 0; i--) {
if ((ua >> i) >= ub) {
ua = ua - (ub << i);
//当res将要加2^31时溢出,返回INT_MIN
if (res > INT_MAX - (1 << i)) {
return INT_MIN;
}
res += 1 << i;
}
}
return sign == 1 ? res : -res;
}
};