前言
位运算是基于整数的二进制表示进行的运算,即运算时是考虑整数对应的二进制表示,并对二进制每一位所考虑的运算。常用的运算符共 6 种,分别为与(&
)、或(|
)、异或(^
)、取反(~
)、左移(<<
)、右移(>>
)和无符号右移(>>>
,只有部分语言才有的特性,比如Java)。其中除了&
以外,其它几个运算符均为二元运算符。
基础介绍
运算符 | 运算规则 |
---|---|
& |
只有两个操作数对应位均为1时才为1,否则为0 |
| |
只有两个操作数对应位均为0时才为0,否则为1 |
^ |
只有两个操作数对应位不相等时才为1,否则为0 |
~ |
将操作数的二进制表示的每一位取反,即0变1,1变0 |
<< |
将操作数的完整二进制表示,去掉高位,低位补0 |
>> |
将操作数的完整二进制表示,去掉低位,若操作数为正数,则高位补0,为负,则补1 |
>>> |
将操作数的完整二进制表示,去掉低位,不管操作数为正还是为负,均补0 |
特别注意
当进行位移运算时,右操作数位移不应该超过整数的最大位数,当然超过了也不会报错,但不同语言的处理细节有所不同,大家如果感兴趣可以看下《深入理解计算机系统》,里面有具体的介绍。
基础使用
为了运算方便,这里假设每个数都只有4位,半个字节,故只能表示-8 ~ 7
,下面先展示每个运算符的使用:
-
&
的使用对于
2 & 3
而言,我们先得到两个数的二进制完整表示:2(0010
), 3(0011
),然后按照&
的规则进行运算:0 0 1 0
&
0 0 1 1
0 0 1 0 (2)
-
|
的使用对于
4 | 1
而言,我们同样先得到两个数的二进制完整表示:4(0100
),1(0001
),然后按照|
的规则进行运算:0 1 0 0
|
0 0 0 1
0 1 0 1 (5)
-
^
的使用对于
6 ^ 2
而言,我们还是先得到两个数的二进制完整表示:6(0110
),2(0010
),然后按照^
的规则进行运算:0 1 1 0
^
0 0 1 0
0 1 0 0 (4)
-
~
的使用对于
~3
而言,我们依旧还是先得到3的二进制完整表示:3(0011
),然后按照~
的规则进行运算:~
0 0 1 1
1 1 0 0 (-4,因为我们上文说了假设数字都是只有四位,因此最高位为符号位)
正数对应的二进制表示,我们一般经过稍加计算很快就可以得到,对于负数的二进制,则可以通过负数相反数进行取反加1得到。例如为了得到-7的二进制,我们首先知道7的二进制为
0111
,然后先进行取反操作,得到1000
,然后再加1,得到1001
,即为-7所对应的二进制表示。 -
<<
的使用对于
1 << 2
而言,我们依然还是先得1
的二进制完整表示:1(0001
),然后按照<<
的规则进行运算:舍去最高的2位得到
01
,然后低位补2个0,得到0100
,0100
(4)即为最终的结果,这里需要注意一点,<<
操作并不是完全等同于将左操作数 * 2右操作数,在计算机里,由于位数的限制,可能会出现运算溢出,因此,对于1 << 3
,按照上述规则得到1000
,由于最高位为符号位,因此得到的结果不是8,而是-8,甚至对于1 << 4
, 按照上述规则会得到0000
,即在这里1 << 4
的结果为0,而非16(正常不应该让位移数操作整数的最大位数,这里仅作讲解使用),大家想要验证的话,可以测试0x4000 0000 << 1
和0x 4000 0000 << 2
(注意这里是16进制的表示形式,转换为二进制表示的话,需要将每一位转换为对应的4位二进制数)即可。 -
>>
的使用由于
>>
为有符号右移,所以这里展示两个例子先说6 >> 2
,我们先得到6的二进制数表示:6(0110
),然后按照>>
的规则进行运算:首先舍去低2位,得到01
,由于为正(最高符号为为0),因此高位需要补2个0,得到0001
(1),即为最终的结果。然后再说一个负数的例子,对于-7 >> 1
,我们先得到-7的二进制完整表示:-7(1001
),然后先舍去低1位,得到100
,由于为负(最高符号为为1),因此高位需要补1个1,得到1100
(-4),即为最终的结果。 -
>>>
的使用>>>
和>>
的唯一区别就是当左操作数为负数的时候,当运算先舍去低位后,高位也同样补0了,而不是7,还是举刚才-7 >>> 1
的例子,我们先得到-7的二进制完整表示:-7(1001
),然后先舍去低1位,得到100
,最后我们在高位补0,得到0100
,即为最终的结果。如果想自己进行代码验证的话,-7的32进制表示为0xffff fff5
,舍弃低位,高位补0,会得到0x7fff fffc
(2147483644)即为最终的结果。特别注意,不管是
<<
、>>
还是>>>
当位移数为0时,得到的结果都是原数。
小结
以上便是关于位运算的基础入门知识,后续还会继续总结位运算的常见技巧以及实际运用等,希望能和大家多多交流,如有错误之处,也请帮忙指出。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/5402.html