程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。
在JavaScript 中,将数字存储为 64 位浮点数,但所有按位运算都以 32 位二进制数执行。
所以执行位运算之前,JavaScript 将数字转换为 32 位有符号整数。
执行按位操作后,结果将转换回 64 位 JavaScript 数。
按位与:&
如果对应的数字位都是 1 ,则该位结果为 1,否则该位的结果为0。
例:
var x = 1 & 2;
数字1的32位2进制是0000 0000 0000 0000 0000 0000 0000 0001
数字2的32位2进制是0000 0000 0000 0000 0000 0000 0000 0010
运算结果32位2进制是0000 0000 0000 0000 0000 0000 0000 0000
转化为10进制是0,即1 & 2 == 0
&运算通常用于二进制的取位操作,例如一个数 & 1
的结果就是取二进制的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数。
按位或:|
如果对应的数字位都是 0 ,则该位结果为0,否则该位的结果为 1。
例:
var x = 5 | 1;
数字5的32位2进制是:0000 0000 0000 0000 0000 0000 0000 0101
数字1的32位2进制是:0000 0000 0000 0000 0000 0000 0000 0001
运算结果32位2进制是:0000 0000 0000 0000 0000 0000 0000 0101
转化为10进制是5 ,即5 | 1 == 5
|
运算通常用于二进制特定位上的无条件赋值,例如一个数 | 1
的结果就是把二进制最末位强行变成1。如果需要把二进制最末位变成0,对这个数 | 1
之后再减一就可以了,其实际意义就是把这个数强行变成最接近的偶数。代码如下
function toInt(num){
return (num | 1) - 1;
}
按位异或:^
如果对应的数字位不同 ,则该位结果为 1,否则该位的结果为 0。
例:
var x = 5 ^ 1;
数字5的32进制2位数:0000 0000 0000 0000 0000 0000 0000 0101
数字1的32位2进制是:0000 0000 0000 0000 0000 0000 0000 0001
运算结果32位2进制是:0000 0000 0000 0000 0000 0000 0000 0100
转化为10进制是5 即5 ^ 1 == 5
^
运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即(a ^ b) ^ b = a
。^
运算可以用于简单讲两个变量的值在不借助第三个变量的情况下进行交换。
按位取反:~
将二进制数的每一位数值都变为反向值,0变成1,1变成0,符号位不变。
例:
var x = ~1;
真码:1000 0000 0000 0000 0000 0000 0000 0001
反码:1111 1111 1111 1111 1111 1111 1111 1110
补码:1111 1111 1111 1111 1111 1111 1111 1111 最终存储方案
~
运算的定义是把内存中的0和1全部取反。使用~
运算时要格外小心,你需要注意整数类型有没有符号。如果~的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,因为无符号类型的数是用00到$FFFF依次表示的。
零填充左位移:<<
一个或多个零数位从右被推入,最左侧的数位被移除,符号位不做移动。
例:
var x = 5 << 1;
数字5的32进制2位数:0000 0000 0000 0000 0000 0000 0000 0101
数字5左位移1位的32进制2位数:0000 0000 0000 0000 0000 0000 0000 1010
转化为10进制是10,即5 << 1 = = 10
公式:数字1 << 数字2,结果:数字1 * 2 ^ 数字2 ,符号为不做移动
有符号右位移:>>
最左侧的数位被从左侧推入,最右侧的数位被移出,符号位不做移动。
例:
var x = 5 >> 1;
数字5的32进制2位数:0000 0000 0000 0000 0000 0000 0000 0101
数字5左位移1位的32进制2位数:0000 0000 0000 0000 0000 0000 0000 0010
转化为10进制是2,即5 >> 1 = = 2
公式:数字1 >> 数字2,结果:整数(数字1 / 2 ^ 数字2),符号为不做移动。
零填充右位移::>>>
一个或多个零数位从左侧被推入,最右侧的数位被移出,符号位也会跟着移动
例:
var x = -5 >>> 1;
数字5的32进制2位数:1000 0000 0000 0000 0000 0000 0000 0101
数字5左位移1位的32进制2位数:0000 0000 0000 0000 0000 0000 0000 1010
转化为10进制是10,即 -5 >>> 1 = = 10