题目描述:
给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。
注意:
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231−1]。本题中,如果除法结果溢出,则返回 231 − 1
var divide = function(a, b) {
const max_val = Math.pow(2,31)-1,min_val = -Math.pow(2,31);
if(a == min_val && b==-1 ){
return max_val;
}
if(a == min_val && b==1 ){
return min_val;
}
//异或为真,确定最终结果的正负
var sign = (a>0) ^ (b>0) ? -1:1;
a = Math.abs(a);
//如果b是min_val,绝对值之后就会变成相反值
b = Math.abs(b);
var n = 0;
for(let i=31; i>=0; i--){
//原本应该会写a >= b<<i,b右移i位,相当于b*(2^i)
//但由于b<<i很容易越界(i一开始是31),所以就变成a左移i位,也就是变成除法,就不容易越界。
if(a >>> i >= b){
a -= b<<i;
n += 1<<i;
}
}
return sign ? -n:n;
}
>>>是无符号左移
var b = -Math.pow(2,31);
b = Math.abs(b);
console.log(b)
console.log(b >> 1)
console.log(b)
结果输出:
2147483648
-1073741824
2147483648
所以为了使得b左移时也能变成正数,就需要用到无符号左移“>>>”
b >> 1 = -1073741824
b >>> 1 = 1073741824