给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
示例 1:
输入: dividend = 10, divisor = 3 输出: 3 示例 2:
输入: dividend = 7, divisor = -3 输出: -2 说明:
被除数和除数均为 32 位有符号整数。 除数不为 0。 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。
public static int divide(int dividend, int divisor) {
//除数-0的处理
if (divisor == 0) {
return Integer.MAX_VALUE;
}
//除数=最小整型数的处理
if (divisor == Integer.MIN_VALUE) {
if (dividend == Integer.MIN_VALUE) {
return 1;
}
return 0;
}
//被除数=最小整型数且除数=-1,结果溢出的处理
if (dividend == Integer.MIN_VALUE && divisor == -1) {
return Integer.MAX_VALUE;
}
//被除数=0直接返回0
if (dividend == 0) {
return 0;
}
//被除数、除数正负位标志
boolean negtive1 = true;
boolean negtive2 = true;
//判断是否为正数
if ((dividend & 0x80000000) == 0) {
negtive1 = false;
//变为负数
dividend = ~dividend + 1;
}
if ((divisor & 0x80000000) == 0) {
negtive2 = false;
divisor = ~divisor + 1;
}
//记录最终结果的正负
if (negtive1 && negtive2 || !negtive1 && !negtive2) {
negtive1 = false;
} else {
negtive1 = true;
}
int target = 0;
int countBit = 0;
int temp = divisor;
//模拟除法运算,先找到除数最大可以左移到多少
while (dividend <= temp) {
//当temp<= -2的29次方,持续翻倍
if (temp >= 0xf0000000) {
temp <<= 1;
//防止左移去掉了符号位
temp |= 0x80000000;
countBit++;
} else {
break;
}
}
//模拟除法逐位的运算
while (countBit >= 0 && dividend <= divisor) {
int count = 0;
//由于都是负数,所以被除数应该小于等于temp
while (dividend <= temp) {
count++;
dividend -= temp;
}
//做了多少次减法,就是该位除之后的结果
target += (count << countBit);
countBit--;
temp >>= 1;
}
//变为负数
if (negtive1) {
target = ~target + 1;
}
return target;
}