位运算
电脑中的器件都是基于二进制的,所以会产生一系列和二进制有关的运算
1.与
对于两个数字(都是 0 或者 1 )
只有两个数字都为 1 时,相与的结果才为 1 ,否则为 0。
与运算用 and 或者符号 & 来表示。
cpp
0 and 0 = 0
0 and 1 = 0
1 and 0 = 0
1 and 1 = 11
2
3
4
2
3
4
2.或
对于两个数字(都是 0 或者 1 )
只要一个数字为 1 时,相或的结果为 1 ,否则为 0。
与运算用 or 或者符号 | 来表示。
cpp
0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 11
2
3
4
2
3
4
3.异或
对于两个数字(都是 0 或者 1 )
当数字为相同时,异或的结果为 0 ,否则为 1。
与运算用 xor 或者符号 ^ 来表示。
cpp
0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 01
2
3
4
2
3
4
4.非
对于两个数字(都是 0 或者 1 )
将数字取非等于把数字反转
非运算用符号 ! 来表示
cpp
!0 = 1
!1 = 01
2
2
5.按位操作
对于两个整数来说,进行与、或、异或操作,相当于先把这两个数字变成二进制数字,然后对应每一位分别进行与、或、异或操作,然后再化为十进制数字
cpp
3 and 5 = 0011 and 0101 = 0001 = 1
3 or 5 = 0011 or 0101 = 0111 = 7
3 xor 5 = 0011 xor 0101 = 0110 = 61
2
3
2
3
其中按位操作还有一个取反操作:
对于一个数据类型,比如 short 它一共有16位,按位取反则就将该数字的二进制每一位都变为原来相反的数字,用符号~ 表示
cpp
~3 = ~ 0011 = 11001
6.左移
将一个数字左移 k 位,相当于把这个数字先化为二进制数,然后再在最后补 k 个 0。
cpp
(5<<2) = (101<<2) = 10100 = 201
如果左移的过多,超出了数据类型能表示的位数,则左侧会消失。
可以看出来,左移 k 位其实和将原数字乘以
7.右移
将一个数字左移 k 位,相当于把这个数字先化为二进制数,然后将最后 k 位删掉,在前面补 k 个 0。
cpp
(5>>2) = (101>>2) = 001 = 11
右移 k 位其实和将原数字除以
左右移的优先级非常低,涉及和别的运算一起写的时候一定要加括号,不加就等死吧。
8.操作一个数的二进制位
判断第 k 位是否为 1:
cpp
if((x>>k)&1);//或者
if(x&(1<<k));1
2
2
改变第 k 为:
cpp
int b=(1<<k);
x=x|b;//将第k位设置为1
x=x^b;//将第k为取反
x=x&(x^b);//将第k位设置为01
2
3
4
2
3
4
P8072 [COCI2009-2010#7] COKOLADA
