位运算及相关常见问题

1. 几种常见的位运算操作

1. 按位与操作&

两个二进制数对应位都为1结果为1,其他情况都为0

2. 按位或操作|

两个二进制数对应位都为0结果为0,其他情况都为1

3. 按位异或操作^

两个二进制数对应位不同结果为1,相同结果为0

4. 按位左移操作<<

将二进制位向左移动,右边空出的部分用0填充

左移1位可以实现乘2的效果,左移2位可以实现乘4的效果…

5. 按位右移操作>>

将二进制位向右移动,右边空出的部分用0或1填充:

如果是有符号数,右边空出来的部分用1填充

如果是无符号数,右边空出来的部分用0填充

右移对于正数来说是除2操作,对于负数不一定,比如-1=11111111(b)

一个简单的demo:

		int a=-1;
		System.out.println(Integer.toBinaryString(a));
		System.out.println(Integer.toBinaryString(a<<1)+"   "+(a<<1));
		System.out.println(Integer.toBinaryString(a>>1)+"   "+(a>>1));
		System.out.println(Integer.toBinaryString(a>>>1)+"   "+(a>>>1));

在这里插入图片描述

6. 按位无符号右移操作>>>

将二进制位向右移动,右边空出的部分用0填充(不用考虑是有符号还是无符号数)

7. 按位补操作~

二进制相应位0变成1,1变成0

2. 常见问题

下面的k都是从右往左数,从1开始

几个基本规律:

  • 某一位与1进行与操作该位不变
  • 某一位与0进行或操作该位不变
  • 某一位与1进行异或操作相当于取反
  • 某一位与0进行异或操作该位不变

1. 检查第k位是否为1

n&(1<<k-1): 结果为1说明第k位是1,否则是0
在这里插入图片描述

2. 将第k位置为1

n|(1<<k-1)

在这里插入图片描述

3. 将第k位置为0

n&~(1<<k-1)
在这里插入图片描述

4. 将第k位取反

n^(1<<k-1)
在这里插入图片描述

5. 将二进制最右边的1变成0

n&(n-1)
在这里插入图片描述

6. 只保留最右边的1,其他位置0

n&-n: -n相当于先对n的补码取反再加1

在这里插入图片描述

7. 最右边的0变成1,其他位置0

-n&(n+1)
在这里插入图片描述

8. 检查某个数是否是2的幂

n&(n-1)==0? 等于0说明是,否则不是,第5条中说到n&(n-1)可以使得二进制最右边的1变成0,而如果一个数是2的次幂,它的二进制中只有1个1,因此执行该操作后就变成0

在这里插入图片描述

9. 将某个数乘以2的幂

给定n,k n变成: n = n × 2 k n=n\times2^k n=n×2k

n<<k: 左移相当于乘2
在这里插入图片描述

10. 将某个数除以2的幂

给定n,k n变成: n = n ÷ 2 k n=n\div2^k n=n÷2k

n>>k: 右移相当于除以2(对于正数成立,负数不一定成立)

11. 计数给定数的模

给定n:

  1. 计算n%8: n&0111n&0x7
  2. 计算n%32: n&00011111n&0x1f
    在这里插入图片描述

12. 反转二进制数

 public int reverseBits(int n) {
        int reverseN=0;
        //n&1: 获得n的最低位  (n&1)<<(31-i):将当前的最低位移动到最高位 
        //这里的最高和最低是相对当前而言
        //第一次循环  最低位是右起第1位  最高位是左起第1位
        //第二次循环  最低位是右起第2位  最高位是左起第2位
        for(int i=0;i<32&n!=0;i++){
            reverseN|=(n&1)<<(31-i);
            n>>>=1;//n右移一位 使得每次n&1得到的都是当前的最低位
        }
        return reverseN;
    }

13. 计算二进制数中1的个数

利用前面的知识:每进行一次n&(n-1)操作可以将二进制的最右边的1变成0,一直重复执行,直到n为0,则执行的次数就是n中含有的1的个数

 public int hammingWeight(int n) {
        int cnt=0;
        while(n!=0){
            cnt++;
            n=n&(n-1);
        }
        return cnt;
    }

14. 奇偶位交换
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodePanda@GPF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值