运算符 | 术语 | 示例 | 结果 |
& | 按位与运算 | 011 & 101 | 2个都为1才为1,结果为001 |
| | 按位或运算 | 011 | 101 | 有1个为1就为1,结果为111 |
^ | 按位异或运算 | 011 ^ 101 | 不同的为1,结果为110 |
~ | 取反运算 | ~011 | 100 |
<< | 左移运算 | 1010 | 10100 |
>> | 右移运算 | 1010 >> 1 | 0101 |
ps:取反、左右位移运算需要在补码的基础上运算。
1、按位与(&)
如果一个为0即为0,两个都为1时才为1
eg:40&15=8
0010 1000 --->40
0000 1111 --->15
-------------------------------
0000 1000 --->8
2、按位或(|)
有1即为1,全0为0
eg:40|15=47
0010 1000 --->40
0000 1111 --->15
-------------------------------
0010 1111 --->47
3、按位异或(^)
相同为0,不同为1
eg:40^15=39
0010 1000 --->40
0000 1111 --->15
-------------------------------
0010 0111 --->39
4、按位取反(~)
对补码进行取反,再将取反后的补码转为原码
(1)正数取反:由于正数的原码、反码、补码相同,即三码合一。
补码(原码) -> 取反(全反) -> 补码逆运算(-1) -> 反码逆运算(符号位不变) -> 原码
eg:~40=0010 1000 ----原码(补码)
=1101 0111 ----补码取反(全反)--补码
=1101 0110 ----补码逆运算(-1)--反码
=1010 1001 ----反码逆运算(取反,符号位不变)--原码
=-41
(2)负数取反:原码 -> 反码 -> 补码 -> 取反 -> 补码(原码)
eg:~-15=1000 1111 ----原码
=1111 0000 ----原码取反(符号位不变)--反码
=1111 0001 ----反码+1 --补码
=0000 1110 -----补码取反(全反)--补码(原码)
=14
5、左移运算符(<<)
将二进制补码全部向左移动,空出来的位置补0,超出范围的二进制数丢弃
eg:40<<4=0010 1000<<4 --三码合一
=1000 0000(特殊情况,不需要逆运算)
=-128
有符号的数据左移后最高位如果为1,则需要进行逆运算
eg:41<<4=0010 1001<<4 ---三码合一
=1001 0000 ----左移四位 --补码
=1000 1111 ----补码-1 --反码
=1111 0000 ----反码取反(符号位不变)--原码
=-112
eg:-41<<4=1010 1001<<4 ---原码
=1101 0110 ----原码取反(符号位不变) --反码
=1101 0111 ----反码+1 --补码
=0111 0000 ---三码合一
=112
运算规则:在一定范围转内,数据每向左移动一位,相当于原数据*2 (正数、负数都适用)
6、右移运算符(>>)
逻辑移位:将数字的二进制补码全部向右移动,空出来的位置补0,超出范围的二进制数丢弃
eg:15 >> 4 = 0000 1111 >> 4
= 0000 0000
= 0
算术移位:左边移入的位由原先该值的符号位决定,符号位为1,则移入的位均为1,符号位为0,则移入的位均为0,这样能保证原数的正负形式不变
eg:-15 >> 2 = 1000 1111 >> 2 ---原码
= 1111 0000 >> 2 ---反码(注意:负数反码符号位不变)
= 1111 0001 >> 2 ---补码
= 1111 1100 ---补码(注意:算术右移左侧空出来的位置需要根据符号位来补位)
= 1111 1011 ---反码(补码转反码只需-1即可)
= 1000 0100 ----反码取反(符号位不变) ---原码
= -4
标准规定:无符号值执行的所有位移操作都是逻辑移位,对于有符号值,到底采用逻辑移位还是算术移位取决于编译器。(一般为逻辑移位)
运算规则:在一定范转内,数据每向右移动一位,相当于原数据/2 (正负数都适用)
注意: 如果不能整除,向下取整
7、例题
(1)num=0x5678ffb3的8-15位取出来
num=(num&(0x0000ff00))>>8
(2)num=0x5678ffb3的第2位值1,其余不变
num|=1<<2
(3)num=0x5678ffb3的第1位值0,其余不变
num^=1<<1
面试题
高效的方法计算2*8的值
2<<3 或 8<<1