# 什么是位运算?
位运算是在数字底层(即表示数字的32个数位)进行运算的,由于位运算是低级的运算操作,所以速度往往也是最快的(相对于其它运算的加减乘除),并且借助位运算有时我们还能实现更简单的程序逻辑,缺点是很不直观,许多场合不能使用
4个位操作符对操作数的个别二进制位执行布尔代数计算,即将操作数中的每一位当成布尔值来对待(1为true、0为false),另外的3个位操作符用于左右移位
提示
位运算只对整数起作用,如果一个运算子不是整数,会自动转换为整数(即丢弃小数部分和第32位以外的部分)再运行,ECMAScript中的所有数值都以IEEE-754 64位格式存储,但位操作符并不直接操作64位的值。而是先将64位的值转换成32位的整数,然后执行操作,最后再将结果转换回64位
ECMAScript
整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数),在ECMAScript
中,所有整数字面量默认都是有符号整数
对于有符号的整数,32位中的前31位(从右向左)用于表示整数的值,第32位用于表示数值的符号,0表示正数,1表示负数,这个标识符号的位叫符号位,数值范围从 -2147483648 到 2147483647。
# js二进制和十进制的转换
let num = 10 // 10进制数
num.toString(2) // 转换为2进制
let num1 = 1001 // 2进制数
parseInt(num1, 2) // 转换为10进制
2
3
4
5
# 按位或(|)
对比每个比特位执行|操作,只有a和b任意一位为1时,a | b就是1,如下表9 | 3
9 | = | 1 | 0 | 0 | 1 |
---|---|---|---|---|---|
3 | = | 0 | 0 | 1 | 1 |
11 | = | 1 | 0 | 1 | 1 |
# 按位与(&)
对比每个比特位执行&操作,只有a和b都为1时,a & b就是1,如下表9 & 3
9 | = | 1 | 0 | 0 | 1 |
---|---|---|---|---|---|
3 | = | 0 | 0 | 1 | 1 |
1 | = | 0 | 0 | 0 | 1 |
# 按位异或(^)
对比每个比特位执行^操作,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0,如下表9 ^ 3
9 | = | 1 | 0 | 0 | 1 |
---|---|---|---|---|---|
3 | = | 0 | 0 | 1 | 1 |
10 | = | 1 | 0 | 1 | 0 |
# 按位非(~)
对任一数值x执行按位非操作的结果为-(x + 1)
,例如:~5结果为-6
~~(5.88) // 取整 5
# 按位移动操作符
按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度,移动的方向根据操作符的不同而不同
# << 左移
左移操作符由两个小于号(<<)表示,该操作符会将数值的所有位向左移动指定的位数,左移操作后会以0来填充空位,以便得到的结果是一个完整的32位二进制数。例如,将数值2(二进制为10)向左移动5位,结果就是64(二进制位1000000)。左移不会影响操作数的符号位,如果将-2向左移动5位,结果将是-64而非64
2 << 5 // 64
-2 << 5 // -64
2
# >> 有符号右移
有符号的右移操作符由两个大于号(>>)表示,该操作符会将数值向右移动,但保留符号位,在移动过程中,原数值出现的空位用符号位用符号位来填充,以便得到一个完整的值