1.在程序中我们常常会用一个字段来记录多种简单的类型,例如,管理员管理帖子的时候,一个帖子有置顶,热议,精品等多个属性。这些属性又比较简单像置顶状态只有置顶和取消置顶两种状态;若是每一个字段都在数据库中加一个字段,若是状态比较多的话,就显的非常冗余;我们可以把这些属性通过位运算(一组特殊数值)存放在一个数据库的一个字段中。我们用这组数值来表示我们的一种状态(如1.置顶 2.取消置顶),之所以称之为一组特殊的数值,是因为这些存放状态的数值必须是2n。
2.什么是位运算?
位运算就是二进制数值按照位运算符&(与),|(或),~(取反),^(异或),>>(左移),<<(右移)对二进制数值进行运算,我们知道 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。
比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
3.二进制和十进制是怎么互相转化的?
十进制和二进制的相互转化:把一个二进制数转化为十进制就是从右到左用二进制的每个数去乘以2的相应次方(次方要从0开始算起);
例如: 1101(2)=1*20+0*21+1*22+1*23=1+0+4+8=13;
4 .二进制位运算符和使用规则:
位运算符号 |
名称 |
规则 |
例子 |
& |
与运算符 |
相同位的两个数字都为1,则为1;若有一个不为1,则为0。 |
1 & 1 =1;0 & 0=0 1 & 0 = 0 ;0 & 1=0 |
| |
或运算符 |
相同位只要一个为1即为1。
|
1 | 1=1 ;0|0=0 1 |0=1;0|1=1 |
^ |
异或运算符 |
相同位不同则为1,相同则为0。 |
1 ^1=0 ;0^0=0 1 ^0=1;0^1=1 |
~ |
取反运算符 |
0和1全部取反。 |
~1=0;~0=1 |
<< |
左移运算 |
右边空出的位用0填补,高位左移溢出则舍弃该高位。 |
|
>> |
右移运算 |
左边空出的位用0或者1填补。正数用0填补,负数用1填补。低位右移溢出则舍弃该位 |
|
4.十进制数2n对应的二进制值,认真研究一下这组数据你就会发现其中的奥妙:
二进制数值 |
00000001 |
00000010 |
00000100 |
00001000 |
00010000 |
00100000 |
01000000 |
10000000 |
100000000 |
十进制数值 |
20 =1 |
21 =2 |
22=4 |
23=8 |
24=16 |
25=32 |
26=64 |
27=128 |
28=256 |
通过仔细观察研究我们发现十进制数1,2,4,8,16,32,64.......2n 。他们转化为二进制进行位运算有一种规律,下面我们通过一个例子来理解这种规律
管理员在管理我们帖子的时候,可以对我们的帖子进行置顶,热议,锁定等操作,我们在数据库中用一个字段Status来记录这些操作,我们可以创建一些枚举值来表示这些操作状态 1 :锁定 2:置顶 4:热议 8:其他状态 。。。。。。。
(1)一个帖子同时是热议和置顶的,那么它的Status=2|4=2+4=6 数据库Status中保留的就是6,若是再锁定,Status=2|4|1=7 数据库Status中保留的就是7。
(2)取消置顶Status= Status&(~2)=6&(~2)=6-2=4(相当于减法)
(3)判断这个帖子是否置顶 Status&2 =6&2=2就说明置顶状态(2)包含在6中;
(1)添加元素:(由于这一组数字都是2n,他们转化为二进制都只是在所在的位上,所以通过或运算实际上就是这两个数相加)
|
|运算符 |
|
1|2 |
00001|00010=00011 |
20|21=20+21=3 |
1|4 |
00001|00100=00101 |
20|22=20+22=5 |
2|8 |
00010|01000=01010 |
21|23=21+23=10 |
1|2|8 |
00001|00010|01000=01010 |
20|21|23=20+21+23=11 |
(2)判断一个元素是否存在:(要判断的那个数若是包含在Status(通过或运算得出来的值)中通过与运算只能得到自己的值)
&十进制运算 |
&二进制运算 |
结果 |
10&8 |
1010&1000=1000 |
8 |
10&2 |
1010&10=0010 |
2 |
11&8 |
1011&1000=1000 |
8 |
(3)移除一个元素:(通过取反运算得到自己数的反数,然后再进行与运算就把这个数个移除了)
十进制 |
二进制 |
十进制结果 |
10&(~8) |
1010&(~1000)=0010 |
2 |
10&(~2) |
1010&(~0010)=1000 |
8 |
11&(~8) |
1011&(~1000)=0011 |
3 |