位运算:
程序中的所有数在计算机内存中都是以二进制的形式存储的。位运算就是直接对整数在内存中的二进制位进行操作。
含义 | C语言 | 操作 |
---|---|---|
按位与 | a & b | 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 |
按位或 | a | b | 两个相应的二进制位中只要有一个为1,该位的结果值为1 |
按位异或 | a ^ b | 若参加运算的两个二进制位值相同则为0,否则为1 |
按位取反 | ~a | ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1 |
左移 | a << b | 用来将一个数的各二进制位全部左移N位,右补0 |
带符号右移 | a >> b | 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数, 高位补0 |
优先级:
1 | ~ |
2 | <<、>> |
3 | & |
4 | ^ |
5 | | |
6 | &=、^=、|=、<<=、>>= |
实用技巧:
一 :判断奇偶
x&1 = 0 偶数
x&1 = 1 奇数
二:消去最后一位1
x & (x-1)
三:取第k位
x >> k & 1
四:将第k位清零(此时右边第一位序号是0)
x = x & ~(1 << k) //右边第一位序号为0时
x = x & ~(1 << k - 1) //右边第一位序号为1时
五: 求两个整数平均值
(x&y)+((x^y)>>1)
六: 判断是否是2的幂
(x&(x-1))
等于0 是
七:交换两个整数
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
八:计算绝对值
(x^y)-y
//(x+y)^y
九:转换成位运算
a % (2^n) 等价于 a & (2^n - 1)
a * (2^n) 等价于 a<< n
a / (2^n) 等价于 a>> n
a % 2 等价于 a & 1
x = x == a ? b : a等价于 x= a ^ b ^ x
x 的 相反数 表示为 (~x+1)
十:枚举子集
思路就是使用一个正整数二进制表示的第i位是1还是0,代表集合的第i个数取或者不取。所以从0到2^n-1总共2^n个整数,正好对应集合的2^n个子集。
S = {1,2,3}
0 000 {}
1 001 {1}
2 010 {2}
3 011 {1,2}
4 100 {3}
5 101 {1,3}
6 110 {2,3}
7 111 {1,2,3}
for(int i=x;i;)
{
i=(i-1)&x;
}