一、逻辑位运算符的介绍
参考: http://c.biancheng.net/view/5469.html
1 、与运算符:&
有0取0,无0取1
第一个数的位值 | 第二个数的位值 | 运算结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
console.log(1&2) // 01&10 =00 : 0
2 、与运算符:|
有1取1, 无1取0
第一个数的位值 | 第二个数的位值 | 运算结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
console.log(1|2) // 01|10=11 : 3
3、异或运算符:^
相同为0,相异为1
第一个数的位值 | 第二个数的位值 | 运算结果 |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
console.log(1^2) // 01^10 =11 : 3
4、非运算符:~
~x = - (x + 1)
位非运算实际上就是对数字进行取负运算,再减 1。例如:
~2 = -3
~5 = -6
~(-10) = 9
一、利用位运算符实现加减法
参考:http://zouyang1230.com/blog/archives/805
1. 加法运算
- 实现:
//加法实现
function add(a,b){
if(a == 0 || b == 0){
return a||b
}
var num;
while(b != 0){
num = a ^ b; //异或:不看进位的结果
b = (a & b) << 1; //与运算且向左移一位:只看进位的结果
a = num;
}
return a;
}
- 分析:
假设a = 9, b = 1
- 我们首先看十进制是怎么实现的加法运算
9 + 1
- 先相加不算进位得到: 0
- 相加只算进位得到 :1
- 进位要乘10得到:10
- 相加不算进位的结果 + 相加只算进位的结果:10 + 0 = 10
- 二进制实现
同理我们可以进位与不进位的结果相加
a 转换为二进制后为 1001
b 转换为二进制后为 0001
- 先相加不算进位得到:1000
- 相加只算进位得到:0001
- 进位要左移一位得到:0010
- 相加不算进位的结果 + 相加只算进位的结果:1000 + 0010 = 1010
而二进制中相加不进位的运算和 ^
(异或:相同为0,不同为1) 的运算一样
二进制中的相加进位的运算和 &
(与运算:都为1则取1,否则为0)的运算一样
但是在实现 “相加不算进位的结果 + 相加只算进位的结果” 时,可能相加后又有进位:
就像1111 + 0001
- 先相加不算进位得到:1110
- 相加只算进位左移一位得到:0010
- 计算相加不算进位的结果 + 相加只算进位的结果: 1110 + 0010
- 先相加不算进位得到:1100
- 相加只算进位左移一位得到:0100
- 计算相加不算进位的结果 + 相加只算进位的结果: 1100 +0100
....
如此循环,所以只有 “相加只算进位” 得到的结果为0时,就可以结束计算,而最终的计算结果就是 “相加不算进位” 得到的结果。
2. 减法运算
- 实现:
function sub(a,b){
if(a == 0 || b == 0){
return a || -b
}
b = ~ b;
var num;
while(b != 0){
num = a ^ b;
b = (a & b) << 1;
a = num;
}
return a + 1;
}
- 分析:
减法运算可以变成加法运算
如11 - 1
=11 + (-1)
只是在这里 1 怎么变成 -1 呢?就要用到我们的~ (非运算)
了
~1 = -(1+1)
所以可以直接套用加法运算 ,只需要在最后的结果再加 1 即可。
另:要注意当a = 0
时,返回的是-b
网友评论