回顾一下位运算

173 阅读1分钟

晚上看直播看到了位运算的部分,之前虽然也了解过,但是没搞懂怎么用

二进制数的位运算

1.按位与 &:对每一个比特位执行与运算,只有参与运算的两位都是1,位运算结果才为1,比如:100 & 101 = 100,两数第一位&运算得1,第二位得0,第三位只有一个1所以也得0。

2.按位或 |:对每一个比特位执行与运算,参与运算的两位有即为1:100 | 101 = 101

3.取反 ~ :对每一个比特位取反,这个不用多说。

4.按位异或 ^: 对每一个比特位执行与运算,参与运算的两位不同则为1:100 ^ 101 = 001

5.左移操作:<< : 把所有位数左移,移出的部分丢弃,右侧用0补齐: 101 << 4 = 1010000

6.右移: >> : 把所有位数右移,移出的部分丢弃,左侧保留剩余部分: 100001 >> 4 = 10

应用:

涉及到权限运算的,可以考虑用位运算

    read = 1
    write = 1 << 1
    remove = 1 << 2
    admin = 1 << 3

假设某个角色role授予权限为 read | write,那么可以用&按位与判断权限:

!!(role & read) // true
!!(role & write) // true
!!(role & remove) // false
!!(role & admin) // false

role的被授权位和权限所在的位都是1,所以这一位一定为1,而role的其他位因为用0补全,所以按位与一定为0,所以按位与最后可以得出true/false的结论

leftpad:

要求:给一个字符串,填充字符串的剩余长度

常规实现很容易,直接拼接字符串就可以:

function myleftpad1(str, length, char) {
    str += ""
    char += ""
    let len = length - str.length
    return Array(len+1).join('0') + str
  }

但是还可以用位运算实现:

function myleftpad2(str, length, char) {
    str += "";
    char += "";
    let len = length - str.length;
    let pad = "";

    while (true) {
      //如果按位与为true,说明这一位有值,所以加上当前循环的char
      if (len & 1) {
        pad += char;
      }
      //每次运算后右移一位,进行下一次循环的比较
      len >>= 1;
      //每次循环计算下次循环对应的char
      if (len) {
        char += char;
      } else {
        break;
      }
    }
    return pad + str;
  }

这么做好处是啥呢?

性能

image.png

性能差距还是挺大的

参考:# 由left-pad扯到JS中的位运算