一直没搞明白这个,今天好好捋了捋
逻辑运算是&&、||这些,而位运算是&、|、^这些。
- &&
逻辑与,这个好理解,必须两边全为真的时候整个表达式才为真,所以它还具有了短路功能,即只要左边为假则不必计算右边的值了 - ||
逻辑或,有一个为真整个表达式就为真。 - &
按位与,即都为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次方。