尽量只对无符号数使用移位运算
右移:丢弃最低位,向下取整,(-1>>1的结果是-1)
左移:有符号数
位运算的优先级,除了取反符高于算术运算符,其他符号都低于算术运算符。
其中& | ^
的优先级甚至低于比较运算符。
判断是否是二的非负整数次幂:
bool isPowerOfTwo(int n) { return n > 0 && (n & (n - 1)) == 0; }
取某一位
// 获取 a 的第 b 位,最低位编号为 0
int getBit(int a, int b) { return (a >> b) & 1; }
置为0
// 将 a 的第 b 位设置为 0 ,最低位编号为 0
int unsetBit(int a, int b) { return a & ~(1 << b); }
置为1
// 将 a 的第 b 位设置为 1 ,最低位编号为 0
int setBit(int a, int b) { return a | (1 << b); }
差集:
a&(~b)
集合A减去集合B中存在的元素
枚举一个集合的非空子集:单次O(2^popcount(s)) 总共(O(3^n))
for(int S = 1; S < (1 << n); ++S) {
for (int s = S; s; s = (s - 1)&S) {
}
}
小心全0的情况:使用longlong要加ll
int __builtin_clz(unsigned int x) //前导零
int __builtin_ctz(unsigned int x) //末尾零
int __builtin_popcount(unsigned int x) //1的个数
31-__builtin_clz(n) // 以2为底的对数