js中位运算的应用

1,387 阅读5分钟

记一笔位运算的应用

先介绍一下,位运算因为是底层匀速计算的速度非常的快,主要原理是根据二进制的每一个比特位进行计算,包括我们现在应用的主流框架`React`、`Vue`等在内部使用的都是位运算的方式,当然有好就有坏缺点就是看起来不是很直观而且学习也要一定的成本

注意:位运算只能是以整数位进行计算,如果一个数不是整数会先转为整数在进行运算在 js 内部,数值都是以64位浮点数的形式储存,但是做位运算的时候,是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数

按位或 `|` ,对二进制的每一个比特位进行或操作如果是0和1会返回1,0和0会返回0

举个例子 当我们计算 2 | 4 的时候。里面的原理是先将2转为二进制之后把4也转为二进制进行比较我们可以通过toString进行转换

2 === 0010

4 === 0100

结果是:0110 将结果转为10进制返回的是6 那么也就是说 2 | 4 会返回6

应用场景:当我们进行取整的时候可以使用 比如 1.2 | 0 返回12.2 | 0会返回2

按位与 `&` ,对二进制的每一个比特位进行与操作如果是0和1会返回0,0和0会返回0,只有是1和1的时候才会返回1

计算的原理和上面讲述的按位或相同

应用场景:我们可以使用按位与来判断一个数的奇偶数,因为二进制最后一位如果为1那么一定是个奇数,所以我们可以这样

奇数 & 1 返回1 ,Number & 1 === 1

举个实际场景的🌰比如一个系统的权限 是 1 2 4 8 分别对应的 0001 0010 0100 1000 那么 A用户权限是 1|2|4|8 = 15 ,B用户权限是4|8=12

那么条件就可以这样:

​ 15 & 1 === 1

​ 15 & 2 === 2

​ 15 & 4 === 4

​ 15 & 8 === 8

​ 12 & 4 === 4

​ 12 & 8 === 8

按位异或 `^` ,对二进制的每一个比特位进行异或操作如果是0和1会返回1,0和0会返回0,1和1返回0

应用场景:

​ 1.可以通过一些条件来切换一个值为0或1 比如 1 ^ 1 = 0 ,0 ^ 1 = 1

​ 2.交换两个变量的值 es6可以有结构赋值的方式[a,b] = [b,a] ,使用位运算可以不用第三个变量

let a = 1,b = 2;

a = a ^ b

b = a ^ b

a = a ^ b

​ 3.还可以做一些简单的字符串加密算法这里就不演示了

按位非 `~` ,对二进制的每一个比特位执行非操作如果是0变成1,1变成0

有几个点需要知道一下:

源码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小

在[计算机](https://baike.baidu.com/item/计算机/140338)系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理

1.对数值进行按位非操作的结果为-(x+1)比如~1返回-2,计算公式 ~(x) = -(x+1)

2.我们读取的十进制是根据源码进行读取的,在内存中,数值都是二进制补码的方式保存的

举个🌰 十进制2的二进制结构 :0000,0010 进行按位非取反结果为1111,1101,正数的补码和源码一样,负数源码转补码或者补码转源码则有其他规则

1.符号位不变,将剩余位取反,得到反码,在反码的基础上最后一位加一得到负数的补码

举个🌰1111,1101转10进制:

​ 1.符号位不变,剩余位取反结果为1000,0010

​ 2.最后一位加1,结果为 1000,0011

​ 3.得到的结果1000,0011就是-3的源码

~(1) = -2

~(2) = -3

应用场景:

1.可以进行取整~~(3.14) 结果为3

2.可以进行indexOf查找

按位移动左移 `<<` ,该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充

举个🌰 1<<2 运算过程👇

1 = 0000 0000 0001

4 = 0000 0000 0100

所以 1<< 2 结果为4

应用场景:可以在rgb颜色和16进制颜色之间转换

按位移动右移 `>>` ,该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。

计算方式:对任何一个数组进行右移n,相当于十进制里的除以10的倍数,这里指的是除以数之后的取整

无符号右移 `>>`该操作符将第一个操作数向右移动指定的位数,向右被移出的位被丢弃左侧用0填充因为符号位变成了0所以结果总是非负的

位运算在正常开发中实际用的并不是很多,但是掌握一部分知识总没坏处