这里主要是讲述位操作符和一些常用的使用场景。作为我对位运算符的学习总结。
这里有一些前提的知识需要提前拿出来说一下,我们都知道Js存储Number类型,无论是浮点数还是整数,都是采用的双精度存储(64)位,上一篇文章我也提到了,因为位操作符不能操作64位的,所以会先转成32位的整数,我们都知道计算机在存储整数的时候都是以补码的形式存储的,正数的补码就是本身,负数是反码+1,为什么计算机存储整数的时候要以补码的形式存储呢?因为CPU只有加法运算器,具体细节自行百度。
~23 === -24
~0 === -1
~100 === -101
拿10举个例子
0000 0000 0000 0000 0000 0000 0000 1010
// ~ NOT
1111 1111 1111 1111 1111 1111 1111 0101
常用场景
向下取整,注意这里只有>0的数可以用,我们都知道向下取整我们一般用Math.floor(),如图这里可以自己动手算一算。根据上面的规则,如图
Array.indexOf中的使用,我们都知道indexOf会返匹配到第一个的下标,没返回那就返回-1。我们在实际项目中判断都是
if (‘米莉波比布朗’.indexOf(‘莉’) > -1) {
}
如果存在’莉’这个字在执行If里的代码,但这看上去并不是那么的简洁。我们知道Boolean(0)为false,但是Boolean(-1)为ture,所以我们可以 if (~‘米莉波比布朗’.indexOf(‘莉’) ) {} 这样写因为~-1为false,别的都为true。
按位与&, 本质上将两个操作数的32位二进制数的每一位对齐。然后按如下的规则取值,1 & 1 等于 1; 1 & 0 等于 0;0 & 1 等于0;0 & 0等于0。
(示例)10和5之间进行按位与操作的结果,等于0:
0000 0000 0000 0000 0000 0000 0000 1010
// & AND
0000 0000 0000 0000 0000 0000 0000 0101
// 等于
0000 0000 0000 0000 0000 0000 0000 0000
按位与|, 本质上将两个操作数的32位二进制数的每一位对齐。然后按如下的规则取值,1 | 1 等于 1; 1 | 0 等于 1;0 | 1 等于1;0 | 0等于0。
(示例)10和5之间进行按位或操作的结果,等于15:
0000 0000 0000 0000 0000 0000 0000 1010
// & OR
0000 0000 0000 0000 0000 0000 0000 0101
// 等于
0000 0000 0000 0000 0000 0000 0000 1111
常用场景
按位异或^, 本质上将两个操作数的32位二进制数的每一位对齐。然后按如下的规则取值,1 ^ 1 等于 0; 1 ^ 0 等于 1;0 ^ 1 等于1;0 ^ 0等于0。
举例:10和5之间进行按位异或操作的结果15。
0000 0000 0000 0000 0000 0000 0000 1010
// ^ XOR
0000 0000 0000 0000 0000 0000 0000 0101
// 等于
0000 0000 0000 0000 0000 0000 0000 1111
常用场景
// 0
100 ^ 100
// 0
-99 ^ -99
// 100
100 ^ 0
// -2
0 ^ -2
在代码中交换两个变量的值,通常是通过第三个变量,或者使用ES6中的解构赋值
// 使用第三个变量
var a = 1
var b = 2
var c = a
a = b
b = c
// 使用解构赋值
var x = 1
var y = 2
[x, y] = [y, x]
使用异或按位运算符
let a = 2
let b = 3
a = a ^ b
// b = a ^ b ^ b => a ^ (b ^ b) => a ^ 0 = a
b = a ^ b
// a = a ^ b ^ a ^ b ^ b => (a ^ a) ^ (b ^ b) ^ b => 0 ^ 0 ^ b => 0 ^ b = b
a = a ^ b
左移(<<)将32位二进制向左移动指定的位数,空缺的位将会使用0填充。左移不会影响符号位。
举例:将5左移2位,等于20。
0|000 0000 0000 0000 0000 0000 0000 0101
// <<2
0|000 0000 0000 0000 0000 0000 0001 0100
// 等于
(2^0 * 0) + (2^1 * 0) + (2^2 * 1) + (2^3 * 0) + (2^4 * 1) = 0 + 0 + 4 + 0 + 16 = 20
常用场景
乘法
左移是乘法,移动的位数是2的幂数
右移(>>)将32位二进制向右移动指定的位数,但是保留符号位,右移空缺的符号位使用0填充。
举例:将31有符号右移3位,等于3。
0|000 0000 0000 0000 0000 0000 0001 1111
// >>3
0|000 0000 0000 0000 0000 0000 0000 0011
// 等于
(2^0 * 1) + (2^1 * 1) = 1 + 2 = 3
常用场景
乘法
右移是除法,移动的位数是2的(幂数 × -1)
无符号位右移,会将所有32位数都向右移动。对于正数来说右移和无符号位右移的结果是一致的。
举例:将-31无符号右移28位。
1111 1111 1111 1111 1111 1111 1110 0001
// >>> 28
0000 0000 0000 0000 0000 0000 0000 1111
// 等于
(2^0 * 1) + (2^1 * 1) + (2^2 * 1) + (2^3 * 1) = 1 + 2 + 4 + 8 = 15