加法
以9+3为例
十进制
1. 不考虑进位,9+3=2(记为sum)
2. 计算进位,9+3=10(记为carry)
对sum和carry持续上两步,直到carry=0 ,sum 即为所求
即:
loop1:(9+3)
sum=2
carry=10
carry!=0
loop2:(sum+carry)
sum=12
carry=0
carry=0
return sum(12)
化成二进制:9(1001);3(0011)
loop1:
sum=1010
carry=0010
carry!=0
loop2:1010+0010
sum=1000
carry=0100
carry!=0
loop3:(1000+0100)
sum=1100
carry==0
return sum(1100=>12)
不难看出,
sum的结果就是异或(num1 ^ num2)结果,
carry就是与运算后左移位1(num1 & num2 << 1)
所以得到位运算加法:
function Add(num1, num2) {
while (num2) {
var t = num1 ^ num2; //不进位的相加
num2 = (num1 & num2) << 1; //同1则进位
num1 = t;
}
return num1;
}
console.log(Add(19, 13));
减法
在十进制中,3-6可以看做 3+(-6),在位运算中也是如此,我们将加法写成减法来运算,二进制中用补码(取反再加一)来表示负数。
所以减法的实现是:补码器 + 加法器
function Add(num1, num2) {
while (num2) {
var t = num1 ^ num2; //不进位的相加
num2 = (num1 & num2) << 1; //同1则进位
num1 = t;
}
return num1;
}
function substract(num1, num2) {
let substr = Add(~num2, 1); // 取反再加一
return Add(num1, substr);
}