Javascript 按位运算解析

1. 按位非 ~

对每一个比特位执行非(NOT)操作。NOT a 结果为 a 的反转(即反码)。

1
2
var num = ~4;
console.log(a); // -5

解析:

4 的二进制数为 100,补满32位

00000000000000000000000000000100

按位取反

11111111111111111111111111111011

由于32位开头第一个是 1,所以这是一个负数,将二进制转换成负数,需要先反码

00000000000000000000000000000100

之后,再+1

00000000000000000000000000000101

转换成十进制为 5,加上符号变成负数 -5

2. 按位与 &

对每对比特位执行与(AND)操作。只有 a 和 b 都是 1 时,a AND b 才是 1。

1
2
var num = 2 & 3;
console.log(num); // 2

解析:

2 的二进制数为 10,3 的二进制数为 11,补满 32 位分别为

2 = 00000000000000000000000000000010

3 = 00000000000000000000000000000011

按位 & 运算,结果为

00000000000000000000000000000010 = 2

3. 按位或 |

对每一对比特位执行或(OR)操作。如果 a 或 b 为 1,则 a OR b 结果为 1。

1
2
var num = 2 | 3;
console.log(num); // 3

解析:

2 的二进制数为 10,3 的二进制数为 11,补满 32 位分别为

2 = 00000000000000000000000000000010

3 = 00000000000000000000000000000011

按位 | 运算,结果为

00000000000000000000000000000011 = 3

4. 按位异或 ^

对每一对比特位执行异或(XOR)操作。当 a 和 b 不相同时,a XOR b 的结果为 1。

1
2
var num = 2^3;
console.log(num); // 1

解析:

2 的二进制数为 10,3 的二进制数为 11,补满 32 位分别为

2 = 00000000000000000000000000000010

3 = 00000000000000000000000000000011

按位 ^ 运算,结果为

00000000000000000000000000000001 = 1

5. 左移 <<

该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。

1
2
var num = 2<<1;
console.log(num); // 4

解析:

2 的二进制数为 10,补满 32 位

2 = 00000000000000000000000000000010

左移 1 位,结果为

00000000000000000000000000000100 = 4

注意:左移不会影响操作符的符号位,例如将 -2 左移 5 位就是 -64

6. 有符号右移 >>

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。

1
2
var num = 9>>2;
console.log(num); // 2

解析:

2 的二进制数为 10,补满 32 位

9 = 00000000000000000000000000001001

右移 2 位,结果为

00000000000000000000000000000010 = 1

相比之下, -9 >> 2 得到 -3,因为符号被保留了:

-9 = 11111111111111111111111111110111

右移 2 位,结果为

11111111111111111111111111111101 = -3

7. 无符号右移 >>>

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(注:即便右移 0 个比特,结果也是非负的。)

1
2
var num = 9>>>2;
console.log(num); // 2

解析:

对于非负数,有符号右移和无符号右移总是返回相同的结果。例如, 9 >>> 2 得到 2 和 9 >> 2 相同:

但是对于负数却不尽相同。 -9 >>> 2 产生 1073741821 这和 -9 >> 2 不同:

-9 = 11111111111111111111111111110111

无符号右移 2 位:

00111111111111111111111111111101 = 1073741821

参考资料