位运算
二进制基础
二进制的位
在机器内部,信息的表示和存储依赖于机器硬件电路的状态。又因为电路只有 “开” 和 “关” 两种状态,因此计算机只能识别“0”和“1”。所以信息的表示(数据)在计算机中是一串01的组合。
二进制与十进制之间的互转
二进制转十进制
进制数的每一位都有一个位权,从右往左是低位到高位,X进制数从右往左数的第i位(从0开始)的位权是X ^ i。
通过计算每一位上的数字与位权的积之和,就可以把X进制数转化成10进制数。
如十进制数567 = 5 * 100(10 ^ 2) + 6 * 10(10 ^ 1) + 7 * 1(10 ^ 0) = 567
。(5的位权是10 ^ 2,6的位权是10 ^ 1)
八进制数1067 = 1 * 512(8 ^ 3) + 0 * 64(8 ^ 2) + 6 * 8(8 ^ 1) + 7 * 1(8 ^ 0) = 567
。
二进制数10110 = 1 * 16(2 ^ 4) + 0 * 8(2 ^ 3) + 1 * 4(2 ^ 2) + 1 * 2(2 ^ 1) + 0 * 1(2 ^ 0) = 22
。
十进制转二进制
使用短除法。
如下,比如十进制数156要转二进制。
最终得到10011100。(如上)
计算一下,1 * 128 + 0 * 64 + 0 * 32 + 1 * 16 + 1 * 8 + 1 * 4 + 0 * 2 + 0 * 1 = 156。
原码、补码、反码
正数的原码、补码、反码都相同。
负数的反码就是原码所有位(除符号位)取反,补码就是反码 + 1。
十六位正整数原码、反码、补码
注:最高位是符号位,0代表正数,1代表负数。
基本位运算
每一位的位运算
按位与(&)
0 & 0 = 0
0 & 1 = 0
1 & 1 = 1
按位或(|)
0 | 0 = 0
0 | 1 = 1
1 | 1 = 1
按位非[取反](~)
~0 = 1
~1 = 0
按位异或(^)
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 1 = 0
按位与、按位或图片
常见位运算
- 判X奇偶:
X & 1
- X * (2 ^ N):
X << N
- X / (2 ^ N)(向下取整):
X >> N
- X * 10:
(X << 3) + (X << 1)
- 取X二进制下的第N位:
1 << N & X
- 设置X的第N位为1:
X |= 1 << N
- 设置X的第N位为0:
X &= 1 << N ^ X
- 求X从低位到高位第一个1的位权:
X & -X
C++运算符优先级
位运算的应用
- 多重背包通过二进制拆分转化成01背包。比如有X个物品,就把X进行二进制拆分即可。https://blog.csdn.net/weixin_43914593/article/details/123703237
- 非递归形式求X ^ Y % Mod 的结果。
- 求所有子集的位操作方法。https://blog.csdn.net/yanzhenhuai/article/details/81572028