一、说明
所有的按位操作符都是按二进制位补码操作
二、按位与 &
有0则为0,全1才是1
例如 3&-5
3的补码: 0000 0000 0000 0000 0000 0000 0000 0011
-5的补码: 1111 1111 1111 1111 1111 1111 1111 1011
3&-5:0000 0000 0000 0000 0000 0000 0000 0011
转换为原码:0000 0000 0000 0000 0000 0000 0000 0011
结果:3
int main() { printf("%d", 3 & -5); return 0; }
三、按位或 |
全0才是0,有1则为1
例如 3 | -5
3的补码: 0000 0000 0000 0000 0000 0000 0000 0011
-5的补码: 1111 1111 1111 1111 1111 1111 1111 1011
3&-5:1111 1111 1111 1111 1111 1111 1111 1011
转换为原码:1000 0000 0000 0000 0000 0000 0000 0101
结果:-5
int main() { printf("%d", 3 | -5); return 0; }
四、按位异或 ^
相同为0,相异为1
例如 3 ^ -5
3的补码: 0000 0000 0000 0000 0000 0000 0000 0011
-5的补码: 1111 1111 1111 1111 1111 1111 1111 1011
3&-5:1111 1111 1111 1111 1111 1111 1111 1000
转换为原码:1000 0000 0000 0000 0000 0000 0000 1000
结果:-8
int main() { printf("%d", 3 ^ -5); return 0; }
五、按位取反 ~
二进制位补码全部取反,包括符号位
例如 ~3
3的补码: 0000 0000 0000 0000 0000 0000 0000 0011
~3:1111 1111 1111 1111 1111 1111 1111 1100
转换为原码:1000 0000 0000 0000 0000 0000 0000 0100
结果:-4
int main() { printf("%d", ~3); return 0; }
六、按位与 & 的实用技巧
任何数字的按位与 1 都可以得到其二进制位原码的最低位
原理:
1的二进制位补码为 0000 0000 0000 0000 0000 0000 0000 0001
数字n的补码最低位和原码最低位是相同的,所以按位与之后得到的补码前31位都是0,最后一位如果是0得到0,如果是1得到1。补码转原码最低位不变,因此可以得到数字n原码的最低位。