位运算概述
计算机所有的数据都是以二进制的形式存储在设备中,即0、1两种状态,计算机对二进制数据进行(+、-、*、/)都是位运算。
例如:计算两数之和
int a=4;
int b=3;
int c=a+b;
电脑是如何让执行这段代码呢
4:1 0 0
3:0 1 1
-------
7:1 1 1
所以,相比于代码中用(+、-、*、/)运算符,用位运算更能显著提交代码执行效率
位运算
按位与运算符( & )
运算规则:
0&0=0 0&1=0 1&0=0 1&1=1
总结:两位同时为1,结果才为1,否则结果为0。
例如:3&5=0011&0101=0001
-3&5=1101&0101=0101 (负数在计算机中用补码表示)
应用
清零:
让其二进制各位都与0相与,结果为0。
取一个数的指定位
比如取数 X=1010 1110 的低4位,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位与运算(X&Y=0000 1110)即可得到X的指定位。
判断奇偶
只要根据最末位是0还是1决定,1为奇,2为偶,所以可以用if((a&1)==0)代替if((a%2)==0)。
按位或运算符( | )
运算规则:
0|0=0 0|1=1 1|0=1 1|1=1
总结:两位有1则1,没1则0。
例如:3 | 5=0000 0011 | 0000 0101=0000 0111
-3 | 5=1111 1101 | 0000 0101=1111 1101
应用
常用来对一个数据的某些位设置为1
比如将数X=1010 1110 的低4位设置为1,只需要找Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y做或运算,(X | Y=1010 1111)
异或运算符( ^ )
运算规则:
0^0=0 0^1=1 1^0=1 1^1=0
总结:两位数相同位相同为0,相异为1。
性质:
交换律
结合律(a^b)^c==a^(b^c)
对于任何数x,都有x^x=0,x^0=x
自反性 a^b^b=a^0=a
应用
翻转指定位
比如将数X=1010 1110 的低4位进行翻转,只需要零找到一个数Y,令Y的低四位为1,其余位为0,即Y=0000 1111,然后将X与Y进行异或运算 (X^Y=1010 0001)即可得到。
与0相异或值不变
例如:1010 1110^0000 0000=1010 1110
交换两个数
void Swap(int &a,int &b) {
if(a!=b) {
a^=b;
b^=a;
a^=b;
}
}
取反运算符 ( ~ )
运算规则
~1=0
~0=1
总结:对一个二进制数按位取反,即将0变1,1变0。
左移运算符( << )
定义:将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
设 a=1010 1110,a = a<< 2 将a的二进制位左移2位、右补0,即得a=1011 1000。
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
应用:
位运算实现乘除法
将x左移以为相当于*2,右移一位相当于/2
x<<1==x*2;
x>>1==x/2;
右移运算符( >> )
定义:将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
例如:a=a>>2 将a的二进制位右移2位,左补0 或者 左补1得看被移数是正还是负。
操作数每右移一位,相当于该数除以2。