JS中的那些位运算

395 阅读4分钟

位运算一直不太懂,所以找了个时间把这个学习了,如果有写的不好请评论联系我纠正

什么是位运算?


位运算是在数字底层(即表示数字的 32 个数位)进行运算的。由于位运算是低级的运算操作,所以速度往往也是最快的(相对其它运算如加减乘除来说),并且借助位运算有时我们还能实现更简单的程序逻辑,缺点是很不直观,许多场合不能够使用

具体计算机的知识,这里我们不进行详解,只要知道一个点 位运算都是以二进制来计算的,所谓位也就是0110中的一位数字

例子:

10进制二进制js中显示二进制
100011
2001010
50101101
1010101010

注: 在二进制中满 2进1,所以 2会等于 0010,js打印二进制,默认会进行去除前面补位的0,如 0001,会变成1,

正式进入正题

  1. 或运算 = a | b

对每一位进行 or 比较, a和b中同位置任意一个二进制位数为1, 既结果为1, 也就是 a | b就是1 ,你也可以理解为 ||

例子: 9 | 3 = 11

十进制=第四位第三位第二位第一位
9=1001
3=0011
11=1011

拿 9的第一位 '1' 和 3的第一位 '1'相比, 满足其中一个有1,所以计算拿出来的结果 第一位等于1,补零也就是: 0001,其他位相同理。

第二位 : 1 第三位: 0 第四位 :1,联合起来: 1011

用处:1取整

let a = 1.5
console.log(a | 0) // 1
//原理:  1.5 => 0001 
//  	   0 => 0000  
//			    0001  输入就是1

  1. 与运算 = a &b

对每一位进行 AND 比较, 同位置两个二进制位数: a和b同时为1, 结果才为1, 也就是 a & b = 1 ,你也可以理解为 &&

例子: 9 & 3 = 1

十进制=第四位第三位第二位第一位
9=1001
3=0011
1=0001

拿 9的第一位 '1' 和 3的第一位 '1'相比, 都为1,计算结果:第一位1,补零也就是: 0001,其他位相同理。

第二位 : 0 第三位: 0 第四位 :0,联合起来: 0001

用处之一:判断奇偶

思路:奇数的二进制最后一位必然为1,所以任意一个奇数 & 1 一定等于1

const isOdd = (num)=> num & 1 === 1;
isOdd(5)
//原理:  1 => 0101 
//  	  0 => 0001  
//			   0001  输入就是1
  1. 异或运算 = a ^ b

    什么是异或: 两个数是否有差异, 1 ^ 1 = 0 因为没有差异,

    1 ^ 0 = 1

对每一位进行 异或 比较, 同位置两个二进制位数: a和b不相等时, 结果才为1, 也就是 1 ^ 0 = 1 ,你也可以理解为 !==

例子: 9 ^ 3 = 1

十进制=第四位第三位第二位第一位
9=1001
3=0011
10=1010

拿 9 的第一位 '1' 和 3的第一位 '1'相比, 没有差异 1 !== 1 =false,计算结果:0, 补零也就是: 0000,其他位相同理。

第二位 : 1 第三位: 0 第四位 :1,联合起来: 1010

用处:交换两个变量(不能三个变量)

let a = 5,
    b = 6;

a = a ^ b; 
b = a ^ b;
a = a ^ b; //这里很重要最后一步还原回去原来的值
  1. 按位非 = ~ a

对每一个比特位执行非(NOT)操作。NOT a 结果为 a 的反转(即反码)

Ps: 对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6:

例子: ~5 = - 6

应用场景:

  1. 取整
~~(-5.88) // -5
  1. 左移动操作符 <<

什么是左移操作符? 将位数向左移动 N 位,并且在右边补 N个0,被左移挤出的位数直接被丢弃

例子: 2 << 2 = 8

十进制=第四位第三位第二位第一位
2=0010
8=1000

2 = 0010

8 = 1000

其实规律就是 number *= 2 ^ n

  1. 左移动操作符 >>

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。

个人简单的理解,就是 例子: 8 >> 2 = 2

十进制=第四位第三位第二位第一位
8=1000
2=0010

8 = 1000

2 = 0010

参考文章-深入研究Js的位运算及用法