29. 两数相除
题目描述
解题思路
这里要考虑溢出
因为题目这里给的dividend(被除数)和divisor(除数)都是int类型
int的边界范围是【-2^ 31 -1 ~ 2 ^31 -1 】
MIN = -2147483648
MAX = 2147483647
可以看出正数和复数 abs(MIN)-abs(MAX) = 1
所以两个数都转换成正数是会有缺失的MIN无法转成int正数(除非你赖皮用long)
说明 MAX 和 MIN是有越界关系
当 dividend = MIN = -2147483648,divisor = -1
dividend / divisor = 2147483648 > MAX (这个时候就越界了)
那么如何处理这个越界问题呢?
我们可以把两个数也就是dividend和divisor全部转换成负数,那么都是负数就只要考虑我们上面的那种情况就可以。
有些注释在下面
代码
class Solution {
public static final int MAX = Integer.MAX_VALUE;
public static final int MIN = Integer.MIN_VALUE;
public int divide(int dividend, int divisor) {
// 溢出情况判断 (根据题目要求,如果除法结果溢出,就返回2^31-1(MAX)
if (dividend == MIN && divisor == -1) {
return MAX;
}
// 用来记录结果的符号
int sign = -1;
if (dividend > 0 && divisor > 0 || dividend < 0 && divisor < 0) {
sign = 1;
}
// 将两个数转换成负数
dividend = dividend > 0 ? -dividend : divisor;
divisor = divisor > 0 ? -divisor : divisor;
int ans = 0;
// 因为是负数 所以是被除数小于除数
while (dividend <= divisor) {
int tmp = divisor, count = 1;
// 这里注意不要写 tmp + tmp >= dividend 这样有可能会溢出(int)
while (tmp >= dividend - tmp) {
// 同时乘以2 count代表是当前(被除数已经乘了几次也就是tmp = divisor * count )
tmp <<= 1;
count <<= 1;
}
// 被除数减去tmp(也就是已经减去多少次的除数)然后把结果加到ans上
dividend -= tmp;
ans += count;
}
// 根据sign判断返回的正负
return sign < 0 ? -ans : ans;
}
}