位运算基础知识
正数和负数在二进制中的表达
正数的二进制状态转负数的二进制:
- -1
- 依次取反
例:
7
的二进制为0111
转为负数则为0110
->1001
负数的二进制状态转正数的二进制,为逆过程:
- 依次取反
- +1
例:
-7
的二进制为1001
转为正数则为0110
->0111
常见的位运算操作符
|
或相同位次中只要出现
1
则返回1
如
0010 | 0111 = 0111
&
与相同位次中都出现
1
则返回1
如
0010 & 0111 = 0010
~
取反0
变成1
,1
变成0
如
~0010 = 1101
^ 异或
相同位次中都不同才返回
1
,否则返回0
。可以看成无进位的相加如
0010 ^ 0111 = 0101
>>
右移 和<<
左移将二进制整体向左/右移动
k
位,多出的位置用0
补如
0010 >> 1 = 0100
0010 >> 1 = 0001
对于非负整数而言 左移相当于扩大
2
的k
次方倍,左移相当于缩小2
的k
次方倍>>>
右移和
>>
功能相同,但是多出的位置用符号位补如
1010 >>> 1 = 1101
一些技巧
取每个位次的数
对于32位的int
类型数据,可以用如下方法依次取出每个位次的数
1 | // 输入num |
向二进制状态填入1
对于0
而言,可以用如下方法向指定位置填入1
1 | ans |= 1 << i; // i为指定位置 |
异或运算的性质和Brain Kernighan算法
异或运算的性质:
a ^ 0 = 0
、a ^ a = 0
- 异或运算可以看成是无进位的相加
- 异或运算满足交换律 即
a ^ b = c
->c ^ b = a
- 负数和正数的相互转化可以用
a = ~a + 1
,相当于a = -a
Brain Kernighan算法
目的:提取出二进制状态最右边的1
1 | int pos = a & (-a); |