1. 原码,反码,补码
名称 | 定义 |
---|
原码 | 最高位是符号位,0代表正数,1代表负数,非符号位为该数字绝对值的二进制。 |
反码 | 正数的反码与原码一致,负数的反码是对原码按位取反,只是最高位(符号位)不变。 |
补码 | 正数的补码与原码一致,负数的补码是对原码按位取反加1,符号位不变。 |
2 逻辑位操作
2.1 基本表
位运算符 | 符号 | 定义 | 例子 |
---|
与 | & | 两个位都为1,结果才为1,否则结果为0。 | 0000 1010 & 0000 1001 = 0000 1000 |
或 | | | 两个位有一个为1,结果就是1,否则结果为0。 | 0000 0011 | 0000 0101 = 0000 0111。 |
异或 | ^ | 如果位为0,结果是1,如果位为1,结果是0。 | 0000 1010 ^ 1111 0111 = 1111 1101。 |
非 | ~ | 两个位相同结果为0,不同结果为1。 | XX |
左移 | << | 将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。 | XX |
右移 | >> | 将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。 | XX |
3 常见的二进制位的变换操作
3 位运算的奇淫技巧
3.1 二进制中1的个数求解
(m = m&(m - 1))
思路:我们发现一个数和该数减1后做按位与操作再赋给该数,即某数=某数&(某数-1),每执行一次,该数二进制最右边的1就会丢掉。那么我们便可以知道,只要一个数在变成0之前能执行多少次某数=某数&(某数-1)操作,该数的二进制便有多少个1。
int count_one(int m)
{
int count = 0;
while (m)
{
m = m&(m - 1);
count++;
}
return count;
}
3.2 判断奇偶数
x & 1 == 1
3.3 交换两个数
x = x ^ y;
y = x ^ y;
x = x ^ y;
3.4 判断符号是否相同
(x ^ y) >= 0