题目链接
思路:
两数相除,其实就是在求被除数中包含有多少个除数。使用位运算对求解过程进行加速
public int divide(int dividend, int divisor) {
// dividend = -2^31, divisor = -1, dividend/divisor = 2^31
if (dividend == Integer.MIN_VALUE && divisor == -1)
return Integer.MAX_VALUE;
// dividend = -2^31, divisor = -2^31, dividend/divisor = 1
if (dividend == Integer.MIN_VALUE && divisor == Integer.MIN_VALUE)
return 1;
// dividend != -2^31, divisor = -2^31, dividend/divisor = 0
if (divisor == Integer.MIN_VALUE)
return 0;
// 此处需要对被除数进行修正并记录修正值:因为下面会对被除数和除数取绝对值,
// 为了避免被除数为整型最小值时,取绝对值会导致越界问题,
// 所以需要对被除数进行修正,即加一个除数
int fix = 0;
if (dividend == Integer.MIN_VALUE) {
// 被除数已为负数,故相加时,除数为负数则应该加除数的绝对值
dividend += divisor > 0 ? divisor : -divisor;
fix = divisor > 0 ? -1 : 1; // 若除数大于0,则最终结果为负,修正值为-1
// 若除数小于等,则最终结果为正,修正值为1
}
boolean neg = (dividend ^ divisor) < 0; // 判断最终结果的符号
dividend = dividend < 0 ? -dividend : dividend; // 取绝对值
divisor = divisor < 0 ? -divisor : divisor; // 取绝对值
int result = 0; // 最终结果
while (dividend >= divisor) { // 当被除数比除数大时,即被除数中依旧包含有除数时
int x = divisor; // 记录除数
int r = 1; // 因为被除数比除数大,所有起码包含有一个除数
while (x <= (dividend >> 1)) { // 除数小于等于被除数除以2时
x <<= 1; // 除数乘以2
r <<= 1; // 结果乘以2
}
dividend -= x; // 减去当前除数所能接近被除数的最大值
result += r; // 当前被除数中包含有r个除数
}
return (neg ? -result : result) + fix; // 返回时判断正负并加上修正值
}