按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。
操作数被转换成 32 位整数,用比特序列(0 和 1 组成)表示。超过 32 位的数字会被丢弃
68719476733 的二进制序列: 1111 11111111 11111111 11111111 11111101
68719476733 << 0 = -3
-3 的二进制序列 11111111 11111111 11111111 11111101
| 运算符 | 用法 | 描述 | |
|---|---|---|---|
| 按位与( AND) | a & b | 对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。 | |
| 按位或(OR) | `a | b` | 对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。 |
| 按位异或(XOR) | a ^ b | 对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。 | |
| 按位非(NOT) | ~ a | 反转操作数的比特位,即0变成1,1变成0。 | |
| 左移(Left shift) | a << b | 将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。 | |
| 有符号右移 | a >> b | 将 a 的二进制表示向右移b(< 32) 位,丢弃被移出的位。 | |
| 无符号右移 | a >>> b | 将 a 的二进制表示向右移b(< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。 |
-
&按位与(and)// 1的二进制表示为: 00000000 00000000 00000000 00000001 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // ----------------------------- // 1 & 3 的结果: 00000000 00000000 00000000 00000001 // 10进制表示为: 1 console.log(1 & 3) // 1 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // 5的二进制表示为: 00000000 00000000 00000000 00000101 // ----------------------------- // 3 & 5 的结果: 00000000 00000000 00000000 00000001 // 10进制表示为: 1 console.log(3 & 5) // 1 // 2的二进制表示为: 00000000 00000000 00000000 00000010 // 4的二进制表示为: 00000000 00000000 00000000 00000100 // ----------------------------- // 2 & 4 的结果: 00000000 00000000 00000000 00000000 // 10进制表示为: 0 console.log(2 & 4) // 0 -
|按位或(or)// 1的二进制表示为: 00000000 00000000 00000000 00000001 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // ----------------------------- // 1 | 3 的结果: 00000000 00000000 00000000 00000011 // 10进制表示为: 3 console.log(1 & 3) // 3 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // 5的二进制表示为: 00000000 00000000 00000000 00000101 // ----------------------------- // 3 | 5 的结果: 00000000 00000000 00000000 00000111 // 10进制表示为: 7 console.log(3 | 7) // 7 // 2的二进制表示为: 00000000 00000000 00000000 00000010 // 4的二进制表示为: 00000000 00000000 00000000 00000100 // ----------------------------- // 2 | 4 的结果: 00000000 00000000 00000000 00000110 // 10进制表示为: 6 console.log(2 | 4) // 6 -
^按位异或(xor)// 1的二进制表示为: 00000000 00000000 00000000 00000001 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // ----------------------------- // 1 ^ 3 的结果: 00000000 00000000 00000000 00000010 // 10进制表示为: 2 console.log(1 ^ 3) // 2 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // 5的二进制表示为: 00000000 00000000 00000000 00000101 // ----------------------------- // 3 ^ 5 的结果: 00000000 00000000 00000000 00000110 // 10进制表示为: 6 console.log(3 ^ 7) // 6 // 2的二进制表示为: 00000000 00000000 00000000 00000010 // 4的二进制表示为: 00000000 00000000 00000000 00000100 // ----------------------------- // 2 ^ 4 的结果: 00000000 00000000 00000000 00000110 // 10进制表示为: 6 console.log(2 ^ 4) // 6 -
~按位非(not)高位舍弃,低位补0
// 由于第一位(符号位)是1,所以这个数是一个负数。JavaScript 内部采用补码形式表示负数,即需要将这个数减去1,再取一次反,然后加上负号,才能得到这个负数对应的10进制值。 // 1的二进制表示为: 00000000 00000000 00000000 00000001 // 1反码二进制表示: 11111111 11111111 11111111 11111110 // 1的反码减1: 11111111 11111111 11111111 11111101 // 反码取反: 00000000 00000000 00000000 00000010 // 表示为10进制加负号:-2 console.log(~ 1) // -2 // 3的二进制表示为: 00000000 00000000 00000000 00000011 // 3反码二进制表示为: 11111111 11111111 11111111 11111100 // 3反码减1: 11111111 11111111 11111111 11111011 // 3反码减取反: 00000000 00000000 00000000 00000100 // 3反码表示为10进制: -4 console.log(~ 3) // -4 -
<<左移(left shift) 将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充由第一个操作数向左移动,因此保留称号位
// 1的二进制表示为: 00000000 00000000 00000000 00000001 // 1 << 3: 00000000 00000000 00000000 00001000 // 10进制表示为: 8 console.log(1 << 3) // 8 // -1的二进制表示为: 11111111 11111111 11111111 11111111 // -1 << 1: 11111111 11111111 11111111 11111110 console.log(-1 << 1); // -2 // 9的二进制表示为: 00000000 00000000 00000000 00001001 // 9 << 2: 00000000 00000000 00000000 00100100 9 << 2; // 36 // -9的二进制表示为: 11111111 11111111 11111111 11110111 // -9 << 2: 11111111 11111111 11111111 11011100 -9 << 2; // -36 -
>>有符号右移(right shift)该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。// 9的二进制表示为: 00000000 00000000 00000000 00001001 // 9 >> 2: 00000000 00000000 00000000 00000010 9 >> 2; // 2 // -9的二进制表示为: 11111111 11111111 11111111 11110111 // -9 >> 2: 11111111 11111111 11111111 11111101 -9 >> 2; // -3 -
>>>无符号右移(unsigned right shift)该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)对于正数,
>>>>>结果相同对于结果,当成是无符号的二进制序列来转
// 9的二进制表示为: 00000000 00000000 00000000 00001001 // 9 >>> 2: 00000000 00000000 00000000 00000010 9 >> 2; // 2 00000111 // -9的二进制表示为: 11111111 11111111 11111111 11110111 // -9 >>> 2: 00111111 11111111 11111111 11111101 -9 >>> 2; // 1073741821 // -9 >>> 1: 11111111 11111111 11111111 11110111 // 将结果当成无符号二进制序列处理,即为: 2^32 - 1 - 2^3 = 4294967287 -9 >>> 0; // 4294967287 // -1073741833的二进制表示为: 10111111 11111111 11111111 11110111 // -1073741833 >>> 0: 10111111 11111111 11111111 11110111 // 将结果当成无符号二进制序列处理,即为: 2^32 - 1 - 2^30 - 2^3 = 3221225463 -1073741833 >>> 0; // 3221225463
应用
-
判断奇偶
// 奇数则二进制末位为1 // 奇数 & 1 = 0 // 偶数 & 1 = 1 2 & 1; // 0 5 & 1; // 1