位运算笔记
对二进制数进行直接操作:
基础操作:
例:
a=0000 1101;
b=0011 0101;
与:a&b==0000 0101;//当两个数的第i位都为1时,a&b的第i位才为1
或:a|b==0011 1101;/*当两个数的第i位都为0时,a|b的第i位才为0
或者说两个数的第i位其中至少有一个为1,对应的a|b的第i位就为1*/
异或:a^b==0011 1000;//当两个数的第i位相同时,a^b的第i位为0,不相同则为1
取反:~a==1111 0010;//前置运算符~,对一个数的所有位进行取反操作 1->0 0->1
取k=2时:
左移:a<<k==0011 0100;//将a朝左边移动k位,超过最高位次的数直接舍弃,增加的低位以0补上
右移:b>>k==0000 1101;//将b朝右边移动k位,超过最低位次的数直接舍弃,增加的高位以0补上
备注:
关于 ^ 运算符有如下操作
结合律: (a ^ b) ^ c == a ^ (b ^ c)
对于任何数 x
,都有 x ^ x = 0
,x ^ 0 = x
自反性:a ^ b ^ b = a ^ 0 = a
lowbit()操作:
lowbit(a)定义为:非负整数 a 在二进制表示下最低位的 1 及其后面的所有的 0 的二进制所构成的数
例:
a=0101 0011;//a=83
b=1100 0000;//b=192
lowbit(a)==1;//0000 0001
lowbit(b)==64;//0100 0000
lowbit()的原理:
int lowbit(int x){
return x&-x;
}
x 对于 -x 进行与操作
-x 等价于 ~x+1 即对x补码
例:
a=1010 0000;
~a=0101 1111;
~a+1=0110 0000;
a&(~a+1)=0010 0000;
补充:
原码、反码、补码操作:
例:a = 1010 0110
a 的原码为其本身,即1010 0110
a 的反码就是对 a 的每一位进行取反操作,和 ~a 相同,即0101 1001
关于补码:
任何大于0的数的补码都等于它的原码,即它本身
任何小于0的数的补码都等于它的反码再加上 1
a 为大于0的数,-a则是小于0的数
备注:
设 x = 0101 0010//82
,~x = 1010 1101//173
存在等式 x + (-x) = 0
那么 -x = 0 - x
,此时内部进行的操作为 0000 0000 - 0101 0010
显然0000 0000
需要向前借位才能进行减法操作
此时有:
1 0000 0000 - 0101 0010 = 1010 1110//174
在8位二进制计算中,能表示的最大值为255,这是因为 0 占去了一个位置
所以说在计算 x 的负值时,我们需要跳过多出的0,从而有:
-x = ~x+1