3.5.2 位操作符
数值 18 的 32 位表示法:00000000000000000000000000010010
其中前 31 位表示整数的值,第 32 位表示数值的符号,0 表示正数,1表示负数。
31 位中的每一位都表示 2 的幂。第一位表示 20,第二位表示 21,以此类推。
负数同样以二进制码存储,但使用的是二进制补码。需要经过下面三个步骤:
- 求这个数值绝对值的二进制码
- 求二进制反码(将0替换成1,将1替换成0)
- 得到的二进制反码 + 1
求 -18 的二进制码:
1、求 18 的二进制码:
0000 0000 0000 0000 0000 0000 0001 0010
2、将 0 和 1 互换
1111 1111 1111 1111 1111 1111 1110 1101
3、将二进制反码 + 1
1111 1111 1111 1111 1111 1111 1110 1101
+ 1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110
按位非(NOT)
~ 表示,返回数值的反码。
const num = 25;
num.toString(2); // '11001' <-- 十进制转二进制
// 00000000000000000000000000011001
const num2 = ~num;
console.log(num2); // -26,操作数的负数 -1
// 等同于
const num3 = -num - 1;
按位非是在数值表示的最底层执行操作,因此速度更快。
按位与(AND)
& 表示,将两个数值的每一位对齐,根据下表中的规则,对相同位置上的两个数进行 AND 操作。
第一个数值的位 | 第二个数值的位 | 结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
对 1 和 4 进行位与操作。
1 & 4; // 0
// 1 的二进制位
0000 0000 0000 0000 0000 0000 0000 0001
// 4 的二进制位
0000 0000 0000 0000 0000 0000 0000 0100
// AND --------------------------------
0000 0000 0000 0000 0000 0000 0000 0000
按位或(OR)
| 表示。
第一个数值的位 | 第二个数值的位 | 结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
对 1 和 4 进行位或操作。
1 | 4; // 5
// 1 的二进制位
0000 0000 0000 0000 0000 0000 0000 0001
// 4 的二进制位
0000 0000 0000 0000 0000 0000 0000 0100
// OR --------------------------------
0000 0000 0000 0000 0000 0000 0000 0101
parseInt('00000000000000000000000000000101', 2); // 转十进制,5
按位异或(XOR)
^ 表示。
第一个数值的位 | 第二个数值的位 | 结果 |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
两个数值位上,只有一个 1 时,才返回 1。
对 1 和 4 进行位异或操作。
1 ^ 4; // 5
// 1 的二进制位
0000 0000 0000 0000 0000 0000 0000 0001
// 4 的二进制位
0000 0000 0000 0000 0000 0000 0000 0100
// XOR --------------------------------
0000 0000 0000 0000 0000 0000 0000 0101
parseInt('00000000000000000000000000000101', 2); // 转十进制,5
对 4 和 4 进行位异或操作。
4 ^ 4; // 0
// 4 的二进制位
0000 0000 0000 0000 0000 0000 0000 0100
// 4 的二进制位
0000 0000 0000 0000 0000 0000 0000 0100
// XOR --------------------------------
0000 0000 0000 0000 0000 0000 0000 0000
parseInt('00000000000000000000000000000000', 2); // 转十进制,0
左移(<<)
将数值的所有位向左移动指定的位数。
const val = 2; // 二进制:10
const val2 = val << 3; // 二进制:10000 十进制:16
有符号的右移(>>)
const val = 16; // 二进制:10000
const val2 = val >> 3; // 二进制:10 十进制:2
无符号右移(>>>)
// -16 的二进制码
11111111111111111111111111110000
// -16 >>> 3
00011111111111111111111111111110 // 右移后 以 0 填充左侧的位
parseInt('00011111111111111111111111111110', 2); // 十进制:536870910