【前端算法系列】位运算

含义运算符示例
左移<<0011 => 0110
右移>>0110 => 0011
按位或|0011 | 1011 => 1011 只要有一个是0就是0
按位与&0011 & 1011 => 0011 相同为1不同为0
按位取反~0011 => 1100 0变1,1变0
按位异或^0011 ^ 1011 => 1000 相同为0不同为1

异或

相同为0,不同为1。也可以用“不进位加法”(加法的个位和不超过9)来理解

  • 全1就是0取反(即1s=~0),x异或全1等于x取反
  • 全0就是0,x异或全0就等于x
// 异或操作:
x^0 = x  // 异或0,只要和0相同为0,不同为本身
x^1s = ~x  //  x异或全1,1s指的是全1,全1就是0取反(即1s=~0),所以x异或全1等于x取反
x^(~x) = 1s // x异或取反x,x取反就是所有二进制位0变为1,1变为0,就是跟x不相同,所以全1
x^x = 0  // 相同为0,不同为1
c=a^b  =>  a^c=b,b^c=a // 交换两个数
a^b^c = a^(b^c) = (a^b)^c  // associative

指定位置的位运算

  1. 将x最右边的n位清零:x&(~0 << n) 把0取反之后全部都是1,然后左移n位
  2. 获取x的第n位置(0或者1):(x>>n)&1
  3. 胡去x的第n位的幂值:x&(1 << (n-1))
  4. 仅将第n位置为1: x | (1<< n)
  5. 仅将第n位置为0:
  6. 将x最高位至第n位(含)清零:x&((1<< n) -1)
  7. 将第n位至第0位(含)清零:x&(~((1<<(n+1))-1))
// 判断奇偶:
x%2==1 --->  (x&1) == 1
x%2==0 --->  (x&1) == 0

// 减半
x >> 1 ---> x/2
mid=(left+right) >>  1 ---> mid=(left+right)/2

// >>> 无论是正数还是负数,高位通通补0
'00000040500' >>> 0  // 40500

x = x&(x-1) 清零最低位的1 (把x最低位的二进制1给去掉)
x&-x => 得到最低位的1
x&~x => 0 

剑指Offer 15. 二进制中1的个数

  1. for循环32次
  2. 先x%2,看最低位是否位1(最后一位),再/2,相当于把最后1位打掉(32次)
  3. x&1,最低位判断是0还是1,x = x >> 1 等于x向右移一位 (32次)
  4. x = x&(x-1) 清零最低位的1,判断x是否为0,即每次清空判断x大于0的情况下不断count累加,每次打掉最后一位1,至道x变成0
    循环次数不再是32次,而是有多少个1就循环多少次
while(x>0){count++; x=x&(x-1)}

231. 2的幂

  • 2的幂次方
  • 2转二进制,第1位必须为1,其余位为0
    n与n-1表示把n的最低位的1打掉,那么这时候n就必须等于0
return n > 0 && (n & (n - 1)) === 0

190. 颠倒二进制位

循环32次,r每次左移一位,n每次右移一位,n & 1取得最右位的数,放入r

写for循环,把每一位都拿出来,把第0位移到第32位,第1位移到32-1位去,即i位移到32-i

var reverseBits = function(n) {
    let res = 0
    for(let i=0;i<32;i++){
        // res先左移腾出最右边一位,然后加上n的最右边一位,然后n再右移一位
        res = (res << 1) + (n&1) 
        n >>= 1
    }
    return res >>> 0
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值