【JS】js中的位运算及应用场景

1.位运算符的定义
位运算是在数字底层(即表示数字的 32 个数位)进行运算的。由于位运算是低级的运算操作,所以速度往往也是最快的(相对其它运算如加减乘除来说),并且借助位运算有时我们还能实现更简单的程序逻辑,缺点是很不直观,许多场合不能够使用。
2.关于二进制
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数)。有符号整数使用 32 位的前 31 位表示整数值。第 32 位表示数值的符号,如 0 表示正,1 表示负。这
一位称为符号位(sign bit),它的值决定了数值其余部分的格式。正值以真正的二进制格式存储,即 31位中的每一位都代表 2 的幂。第一位(称为第 0 位)表示 20(2的0次方),第二位表示 21,依此类推。如果一个位是空的,则以0填充,相当于忽略不计,比如,数值18的二进制格式为00000000000000000000000000010010,或更精简的 10010。后者是用到的 5 个有效位,决定了实际的值,如下图
【JS】js中的位运算及应用场景
3.二进制和十进制
3.1js代码进行转化

// 十进制 => 二进制

let num = 10;

console.log(num.toString(2));

// 二进制 => 十进制

let num1 = 1001;

console.log(parseInt(num1, 2));

3.2手动转化

// 二进制 => 十进制

【JS】js中的位运算及应用场景

// 十进制 => 二进制,使用短除法

【JS】js中的位运算及应用场景
4.概况
【JS】js中的位运算及应用场景

5.详解及应用
5.1按位或 |
|与||操作符的道理也是一样的,只要两个数中有一个数为1,结果就为1,其他则为0
【JS】js中的位运算及应用场景
5.1.1 或|的应用场景
用或 | 操作,在实际应用中,我们可以实现向下取整,即int = num | 0,因为位运算是对整数操作的,当遇到浮点型的数值时,会先将浮点型的数据转成整型,然后再进行或运算,因为|只有其中一个数为1结果就是1,而0的二进制也是0,所以可实现向下取整

    3.7 | 0  //3

1.1 | 0 //1

5.2按位与 &
&运算符表示只有两个数的值为1时,才返回1
【JS】js中的位运算及应用场景
5.2.1 &的应用场景
我们管理系统做表单checkbox多选是,加入我们有a、b、c、d四个chebox的选项,1,2,4,8分别代表checkbox的value值,当我们全选a + b + c + d的时候,可以将1 | 2 | 4 | 8 = 15传给java后台,如果只选择a + c的时候,则传递给java后台的值为1 | 4 = 5。
那么我们做编辑功能的时候,如何判断checkbox是否被选中?很简单,用&符号就可以,比如用户选择了a+c,后台给我们返回5,c的值为1,那么 4 & 5 = 4, b的选项我们是没有选择的,则 2 & 5 = 5,也就是说,选中的通过&的运算值为>0的值,没有选中的将会为0。

1 | 2 | 4 | 8 = 15

1 | 4 = 5

4 & 5 = 4

2 & 5 = 0

这种实现方式在做系统权限特别好友,不过要特别注意的是,checkbox的值必须为2的幂次方,并且最大值为2的31次方。
5.3 按位异或 ^
两个操作数相应的比特位有且只有一个1时,结果为1,否则为0

【JS】js中的位运算及应用场景
5.3.1应用场景
(1)假如我们通过某个条件来切换一个值为0或者1

    //普通的写法

function update(toggle) {

var num = toggle ? 1 : 0;

console.log(num)

}

update(true);

// 通过异或我们可以这么写

num = num ^ 1; //num为true的返回 0, 为 false返回1

(2)可以在不使用第三变量的值得情况下交换两个变量的值

    let a = 5,

b = 6;

a = a ^ b;

b = a ^ b;

a = a ^ b;

(3)可以实现简单的加密

const key = 313;

function encryption(str) {

let s = '';

str.split('').map(item => {

s += handle(item);

})

return s;

}

function decryption(str) {

let s = '';

str.split('').map(item => {

s += handle(item);

})

return s;

}

function handle(str) {

if (/\d/.test(str)) {

return str ^ key;

} else {

let code = str.charCodeAt();

let newCode = code ^ key;

return String.fromCharCode(newCode);

}

}

let init = 'hello world 位运算';

let result = encryption(init); // őŜŕŕŖęŎŖŋŕŝę乴軩窮

let decodeResult = decryption(result); // hello world 位运算

5.4 按位非~
按位非就是求二进制的反码的操作。对数值进行非运算主要有一下步骤:

(1)求数值二进制,如var num = 1; // 二进制 00000000000000000000000000000001

(2)取该值得反码为: num2 = 11111111111111111111111111111110

(3)第32位符号位的值不变,num2其他为位在取反码后位 num3 = 10000000000000000000000000000001

(4)然后加1为10000000000000000000000000000010,即-2,也就是1的按非~运算结果为-2

5.4.1应用场景

// 常用判断

if (arr.indexOf(item) > -1) {

// code

}

// 按位非 ~-1 = - (-1 + 1)

if (~arr.indexOf(item)) {

// code

}

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

例如 3 << 2 的运算图示如下:

3 = 0000 0000 0000 0000 0000 0000 0000 0011

12 = 0000 0000 0000 0000 0000 0000 0000 1100

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

例如3>>2

3 = 0000 0000 0000 0000 0000 0000 0000 0011

0 = 0000 0000 0000 0000 0000 0000 0000 0000

5.7 无符号右移>>>
该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)

    var num = -64; // 11111111111111111111111111000000(负数采用的是补码表示)

num = num >>> 5; // 134217726

//求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1

6.总结
位运算是在数字底层进行操作的,运算速度快,书写简洁,但是很多场景没法使用,也不够直观。

以上是 【JS】js中的位运算及应用场景 的全部内容, 来源链接: utcz.com/a/95975.html

回到顶部