一、基础知识
- &:与:两个位都为1时,结果才为1
3&5 即 0000 0011 & 0000 0101 = 0000 0001,因此 3&5 的值得1
- |:或:两个位都为0时,结果才为0
3|5即 0000 0011 | 0000 0101 = 0000 0111,因此3|5的值得7
- ^:异或:两个位相同时为0,相异时为1
3^5即 0000 0011 ^ 0000 0101 = 0000 0110,因此3^5的值得6
//交换两个数
void Swap(int &a, int &b)
{
if (a != b)
{
a ^= b;
b ^= a;
a ^= b;
}
}
- ~:取反:0变成1,1变成0
~3即 ~ 0000 0011 = 1111 1100,因此~3的值得508
使a的最低位为0,可以表示为:a & ~1。~1的值为 1111 1111 1111 1110,再按"与"运算,最低位一定为0
- <<:左移:各二进位全部左移若干位,高位丢弃,低位补0
- >>:右移:各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)
- 原码:最高位为符号位,0表示正数,1表示负数
x = 0b11 (3),四比特表示原码 0011(3) ;x = - 0b11(-3) ,四比特表示原码 1011(11) ;
- 反码:最高位为符号位,0表示正数,1表示负数;正数的反码等于本身,负数的反码除符号位外,各位取反
x = 0b11 (3),四比特表示原码 0011(3),对应反码为 0011(3) ;x = - 0b11(-3) ,四比特表示原码 1011(11),对应反码为 1100(12),补码为1101(13)
- 补码: 最高位为符号位,0表示正数,1表示负数;正数的补码等于本身,负数的补码等于反码+1:
x = 0b11 (3),四比特表示原码 0011(3),对应反码为 0011(3) ,补码为 0011(3);x = - 0b11(-3),四比特表示原码 1011(11),对应反码为 1100(12),补码为 1101(13);
二、应用
1.n的二进制表示中第k位是几?
- 先把第k位移到最后一位n>>k
- 看个位是几:x&1
n>>k&1(优先级从左往右)
2.lowbit(x):返回x的最后一位1 【树状数组基础】
x=1010,则lowbit(x)=10;x=101000,则lowbit(x)=1000
- 实现方法:x&-x =x&(~x+1)
x = 1010......100......0
~x = 0101......011......1
~x+1 = 0101......100......0
x&(~x+1) = 0000......100......0