整数除法
题目
给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 。
注意:
- 整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31−1]。本题中,如果除法结果溢出,则返回 2^31 − 1
思路
除法不能用 *、/、% ?那该怎么办呢?将除数叠加以至等于被除数,或者被除数叠减以至于除数
如果存在两个数正负号不相同呢?考虑符号问题
考虑边界溢出问题,比如:-2^31 / -1 = 2^31
这个时候就要做边界处理
代码
1. 叠减法
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var divide = function (a, b) {
// 考虑数值溢出问题
const MAX = Math.pow(2, 31) - 1;
const MIN = -Math.pow(2, 31);
if (a == MIN && b == -1) {
return MAX;
}
if (a == MIN && b == 1) {
return MIN;
}
// 异或运算直接判断符号是否相同
const isNegative = (a > 0) ^ (b > 0);
a = Math.abs(a);
b = Math.abs(b);
let time = 0;
// 不断叠减以至于除数小于被除数
while (a >= b) {
a -= b;
time++;
}
return isNegative ? -time : time;
};
2. 位运算
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var divide = function (a, b) {
const MAX = Math.pow(2, 31) - 1;
const MIN = -Math.pow(2, 31);
if (a == MIN && b == -1) {
return MAX;
}
if (a == MIN && b == 1) {
return MIN;
}
const negative = (a > 0) ^ (b > 0);
a = Math.abs(a);
b = Math.abs(b);
let time = 0;
// 这段位运算无法理解
for (let x = 31; x >= 0; x--) {
if ((a >>> x) - b >= 0) {
a = a - (b << x);
time = time + (1 << x);
}
}
return negative ? -time : time;
};