前端算法系列(11):位运算

239 阅读2分钟

概述

首先要明确一些基础概念,位运算间有一些常见位操作。

逻辑位操作

  • ~ 按位取反,对每一位执行非操作,最终结果是~x=-(x + 1)
  • & 按位与,对每对比特位执行与操作,当两者都是1时才是1
  • | 按位或,对每一对比特位执行或操作,当两者都为0才是0,比如x|0表示x取整
  • ^ 按位亦或,每对不同时为1

二元位操作具有交换律和结合律

移动操作符

  • << 左移操作符 左移超过的比特位会被丢弃,右侧用0补充,x<<y=x * 2 ** y.
  • >> 右移操作符 右移超过的会被丢弃,复制最左边的比特位补充,由于符号位不变因此称为符号传播
  • >>> 无符号右移 右移超过的会被丢弃,左侧补0,因此符号位会变成0,正数和一般右移相同

常利用的位操作性质

  • 判断奇偶 x&1===1(奇)
  • x>>1 即Math.floor(x/2)
  • x=x&(x-1) 清除最低位的1,当x-1时最低位1及后面的位会取反,因此被置为0
  • x&-x 清除最低位1之外的1,比如2为10b,-2为31个1,一个0,得10b,即2

例题

  • 汉明距离 计算两个数二进制不同的位数,只需要计算亦或操作中1的个数
  • 颠倒二进制位 设返回值为0,每次左移1位+被操作数最后一位,重复32次,返回之前右移0位保证正数。
/**
 * @param {number} n - a positive integer
 * @return {number} - a positive integer
 */
var reverseBits = function(n) {
  //初始值result=0
      let result = 0;
    //对32位依次进行处理
    for(let i = 0;i < 32;i++){
      //对result左移一位,并在末尾加上n当前最后一位,n&1即把n的最后一位和1取与,其他位和0取与结果为0
        result = (result << 1) + (n & 1);
        //n右移,把最后一位丢弃
        n >>= 1;
    }
   //当符号位为1时表示负数,因此最后需要无符号右移,将有符号整数变成无符号
    return result >>> 0;

};