二进制中含有1的个数

看到剑指Offer中二进制中1的个数这个题目,才感觉到位运算的强大。原来整数不用换成二进制,遇到位运算符会自动变成二进制进行计算。所以当输入的数为负数时,也不用考虑负数的表示问题,因为在进行二进制运算时,系统会自动将其以补码形式表示。

num & 1 为真则说明num是奇数,为0则说明num是偶数

例如二进制:num = 0110 1011 中含有多少个1呢,当num & 0000 0001 结果为1说明num右边第一位为1,当num & 0000 0010 结果为1,说明右边数第二位也为1;

所以定义 int  flag = 1;flag << 1左移一位与num进行与计算 判断二进制每一位是否为1,当flag结果为0时,循环结束

具体代码如下所示:

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         int flag = 1;
         while(flag)
         {
             if(n&flag)
                 count++;
             flag = flag << 1;             
         }
         return count;
     }
};

位运算的优先级:


下面列举了一些常见的二进制位的变换操作。

功能 | 示例 | 位运算

----------------------+---------------------------+--------------------

去掉最后一位 | (101101->10110) | x>>1

在最后加一个0| (101101->1011010) | x<<1

在最后加一个1| (101101->1011011) | x<<1+1

把最后一位变成1| (101100->101101) | x|1

把最后一位变成0| (101101->101100) | x| 1-1

最后一位取反 | (101101->101100) | x^ 1

把右数第k位变成1 | (101001->101101,k=3) | x|(1<< (k-1))

把右数第k位变成0 | (101101->101001,k=3) | x& ~(1<<(k-1))

右数第k位取反 | (101001->101101,k=3) | x^(1 shl (k-1))

取末三位 | (1101101->101) | x&7

取末k位 | (1101101->1101,k=5) | x&(1<<(k-1)

取右数第k位 | (1101101->1,k=4) | x>>(k-1)&1

把末k位变成1| (101001->101111,k=4) | x|(1<<k-1)

k位取反| (101001->100110,k=4) | x^ (1<<k-1)

把右边连续的1变成0 | (100101111->100100000) | x&(x+1)

把右起第一个0变成1 | (100101111->100111111) | x| (x+1)

把右边连续的0变成1 | (11011000->11011111) | x| (x-1)

取右边连续的1 | (100101111->1111) | (x^ (x+1))>>1

去掉右起第一个1的左边| (100101000->1000) | x&(x^(x-1))(或x&(-x)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值