位运算与逻辑运算

一直没搞明白这个,今天好好捋了捋
逻辑运算是&&、||这些,而位运算是&、|、^这些。

  • &&
    逻辑与,这个好理解,必须两边全为真的时候整个表达式才为真,所以它还具有了短路功能,即只要左边为假则不必计算右边的值了
  • ||
    逻辑或,有一个为真整个表达式就为真。
  • &
    按位与,即都为1结果才为1,
    2(010)&7(111)的结果为2(010)
  • |
    按位或,只要有1就为1
  • ^
    异或,我的理解就是按位相加,扔掉溢出
    2(010)^7(111)的结果为5(101)

接下来是一些比较有意思的应用

  • 比如求2和7的平均数,可以套用((x&y)+(x^y)>>1)
    2&7 = 2(010)
    2^7 = 5(101)
    5>>1 = 2(10)
    010+010 = 4(100)
    即2和7的平均数为4.

  • 求解整数在二进制下1的个数

int func(int x)
{
    int count = 0;
    while(x)
    {
        count++;
        x = x & (x - 1);
    }
    return count;
}

这里面先是x-1,当一个数被减一时,它最右边为1的值将变成0,同时其右边所有的值变成1,这个很容易验证,111减1是110,110减1是101.
也就是当减一时,最右边的一急以后的数字都取反了,这样再与原数字相与,由于只有全为1才会是一,所以最右边的1及以后的数全变成0了。
7的二进制是111,6的二进制是110,相与得110,不断进行下去,有多个1就会进行多少次,直到全部变成0,结束循环。

  • 获取整数n的二进制中最后一个1
    n&(-n)
    注意 -n = ~(n - 1)

10/5更新
关于<<
左移相当于乘法运算,右移运算相当于除法运算。
将一个数左移n位,相当于乘以了2的n次方。
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值