《C++新经典》第11章 位运算
11.1 位的概念和位运算符简介
11.1.1 位的概念
1字节由8个二进制位组成,最左边的位称为最高位,最右边的位称为最低位,每个二进制位的值是0或者1。
11.1.2 位运算符简介
- 按位与运算符&
两个运算量相应位都为1时为1,否则为0。
0&0=0;0&1=0;1&0=0;1&1=1。
unsigned int temp = 38 & 22; //6
00100110 //38
&
00010110 //22
--------
00000110 //6
- 按位或运算符|
两个运算量相应位存在1时为1,否则为0。
0|0=0;0|1=1;1|0=1;1|1=1。
unsigned int temp = 38 | 22; //54
00100110 //38
|
00010110 //22
--------
00110110 //54
- 按位异或运算符^
两个运算量相应位不同为1,相同为0。
0^0=0;0^1=1;1^0=1;1^1=0。
unsigned int temp = 38 ^ 22; //48
00100110 //38
^
00010110 //22
--------
00110000 //48
- 保持二进制位不变,可以和0做异或运算,可以和1做与运算,可以和0做或运算
0^0=0,1^0=1
;0&1=0,1&1=1
;0|0=0,1|0=1
- 翻转二进制位(0,1互变),可以和1做异或
0^1=1,1^1=0
11000011
^
00001111 //高4位不变,低4位翻转
--------
11001100
- 取反运算符~
对一个运算量的位取反,0变1,1变0。
~0=1;~1=0。
unsigned int temp = ~38; //4294967257
~
00000000 00000000 00000000 00100110 //38
--------
11111111 11111111 11111111 11011001 //4294967257
- 左移运算符<<
一个数的二进制位左移若干位,右侧补0,每左移一位等价于乘以2(未溢出时)。
unsigned int temp = 15<<1; //15*2, 30
00001111 //15
<<1
--------
00011110 //30
- 右移运算符>>
一个数的二进制位右移若干位(舍弃若干右侧最低位),左侧始终补0(逻辑右移)或者补0或1(算术右移,根据最高符号位决定),每右移一位等价于除以2(未溢出时)。
unsigned int temp = 15>>1; //15/2, 7
00001111 //15
>>1
--------
00000111 //7
位运算符和赋值运算符结合得到复合赋值运算符。
&=,|=,^=,<<=,>>=
11.2 位运算的具体应用
unsigned,32位,最右边最低位(第1位),最左边最高位(第32位),32个状态。
#define BIT(x) (1<<(x))
int i;
for(i=0; i<10; i++)
printf("BIT(%d)=%d\n", i, BIT(i)); //1,2,4,8,16,32,...,512
enum EnumTask {
ETask1 = BIT(0),
ETask2 = BIT(1),
ETask3 = BIT(2),
ETask4 = BIT(3),
ETask5 = BIT(4),
ETask6 = BIT(5),
ETask7 = BIT(6),
ETask8 = BIT(7),
ETask9 = BIT(8),
ETask10 = BIT(9),
}
unsigned task = 0;
if(task & ETask7) {
printf("task第7位为1\n");
} else {
printf("task第7位为0\n");
task |= ETask7; //task第7位设置为1
}
if(task & ETask7) {
printf("task第7位为1\n");
}