位运算符
1.位逻辑运算符
· &(AND,与运算)
执行AND运算时,对应的两个位(bit)都为1时,运算结果才为1,否则为0。例如,a=12,则a&38得到的结果为4,因为12的二进制表示法为1100,38的二进制表示法为00100110,两者执行AND运算后,结果为十进制的4。运算过程如图3-3所示。
· |(OR,或运算)
执行OR运算时,对应的两位(bit)只要任意一个为1,运算结果就为1,也就是说只有两位都为0时,运算结果才为0。例如,a=12,则a|38得到的结果为46,运算过程如图3-4所示。
· ^(XOR,异或运算)
执行XOR运算时,参与运算的两位只有一个为1,运算结果就为1,同时为1或0时,结果则为0。例如,a=12,则a^38得到的结果为42,运算过程如图3-5所示。
· ~(NOT,非运算)
NOT的作用是取1的补码(complement),在二进制中也就是0与1互换。例如,a=12,二进制表示法为1100,取1的补码后,由于所有位都会进行0与1互换,因此运算后的结果得到-13,运算过程如图3-6所示。
2.位位移运算符
C++中提供有两种位逻辑运算符,分别是左移运算符(<<)与右移运算符(>>)。
· <<(左移)
左移运算符(<<)可将操作数的各个位(bit)向左移动n位,左移后超出存储范围即舍去,右边空出的位则补0。
例如,表达式“12<<2”。数值12的二进制值为1100,向左移动2位后成为110000,也就是十进制的48。运算过程如图3-7所示。
· >>(右移)
右移运算符(>>)与左移相反,可将操作数的各个位(bit)右移n位,右移后超出存储范围即舍去。这里请注意,这时右边空出的位,如果这个数值是正数则补0,负数则补1。
例如,表达式“12>>2”。数值12的二进制值为1100,向右移动2位后成为0011,也就是十进制的3。运算过程如图3-8所示。
接下来我们还要讨论负数与左移运算符(<<)与右移运算符(>>)的关系,如果是-12<<2与-12>>2,那么结果是什么呢?首先我们要求出-12的二进制表示法,方法如下:
(1)12的二进制表示法如下:
(2)取1的补码,这时将1改为0,0改为1。所谓“1的补码”是指如果两数之和为1,则此两数互为1的补码,亦即0和1互为1的补码:
(3)取2的补码,只要将1的补码加上1即可,至于“2的补码”的做法则是必须事先计算出该数的1补码,再加1即可:
接下来进行-12<<2的运算,即左移2位,如果超出存储范围就舍去,右边空出的位则补0,得到如下的二进制数:
这时将此数减1可得1的补码:
然后又还原回去,也就是将1改为0,0改为1,我们知道是负数,所以所得的结果还要乘以-1:
如果是-12>>2的运算,就右移2位:
右移后超出存储范围即舍去,而右边空出的位,如果数值是正数就补0,负数就填1:
将此数减1,可得1的补码:
然后又还原回去,也就是将1改为0,0改为1,我们知道是负数,所以所得的结果还要乘以-1:
- 参考:
《从零开始学C++程序设计》(吴惠茹等)——机械工业出版社