运算符 | 解释 | 例子 |
---|---|---|
与& |
对应位上两个数都为\(1\)结果为\(1\),反之为\(0\) | 101 & 001 = 001 |
或| |
对应位上两个数有一个为\(1\)结果为\(1\),反之为\(0\) | 101 | 010 = 111 |
异或^ |
对应位上两个数不一样为\(1\),反之为\(0\) | 101 ^ 100 = 001 |
特别的异或的逆运算仍是异或,( a ^ b ) ^ b = a
优化
~
一个数的每一位取反,~ 1001 = 0110
spa
注意这里的~
是按位取反,!
是逻辑取反code
左移(>>
)把二进制的每一位向左移动,多余的舍弃,右侧补0
注意可能会移到符号位上,致使变成负数get
右移(<<
)把二进制的每一位向右移动,多余的舍弃,左侧补0
table
注意左移右移的运算优先级低于加减,因此a << 1 + 1 = a << ( 1 + 1 )
class
a << i
等价于\(a \times 2^i\)二进制
a >> i
等价于\(a\div 2^i\)im
a * 10 = ( a << 3) + ( a << 1 )
tab
若是用二进制数来表示集合,还有一些集合运算集合
操做 | 集合表示 | 位运算操做 |
---|---|---|
交集 | $a \cap b $ | a & b |
并集 | \(a \cup b\) | a | b |
补集 | \(\overline a\) | ~ a |
枚举子集
for( register int i = x ; i ; i = ( i - 1 ) & x );
下面的写法,在必定程度上能够优化常数
判断奇偶
if( x & 1 ) = if( x % 2 )
交换两个数
inline void swap( int & x , int & y ) { x ^ y ^ x ^ y;}
判断两个数符号是否相同
inline bool isSameSign(int x, int y) { // 有 0 的状况例外 return (x ^ y) >= 0; // true 表示 x 和 y 有相同的符号,false 表示 x,y 有相反的符号。 }
求平均值
inline int getAverage( int x , int y ) { return (x + y) >> 1; }