在阅读JDK源码的过程中,我们经常会看到类似>>
<<
>>>
|
这样的运算符,这在Java里面叫位运算符。
我们知道计算机是以二进制来表示数据的,也就是0和1。我们先简单介绍一下二进制是如何表示数据的。
原码、反码、补码和移码
(1)原码
在原码表示中,机器数的最高一位是符号位,0代表正号,1代表负号,余下各位是数的绝对值。
数值0的原码表示方法有两种: $[+0]_原$ = 0000 0000 , $[-0]_原$ = 1000 0000。
8位二进制数的取值范围是:[-127 , 127]
(2)反码
在反码表示中,机器数的最高一位是符号位,0代表正号,1代表负号。
正数的反码与原码相同;
负数的反码则是其绝对值按位求反。
数值0的反码表示方法有两种: $[-0]_反$ = 0000 0000 , $[-0]_反$ = 1111 1111。
(3)补码
在补码表示中,机器数的最高一位是符号位,0代表正号,1代表负号。
正数的补码与原码相同;
负数的补码则是其反码的末尾加1。
数值0的补码有唯一的表现形式,即 $[-0]_补$ = $[-0]_补$ = 0000 0000。
(4)移码
移码表示法是在数上增加一个偏移量来定义的,常用于表示浮点数中的阶码。对于定点整数,移。如果知道了一个数的补码,则将补码的最高位取反,即得到该数的移码。
位运算符
Java提供的位运算符有:左移( <<
)、右移( >>
) 、无符号右移( >>>
) 、位与( &
) 、位或( |
)、位非( ~
)、位异或( ^
),除了位非( ~
)是一元操作符外,其它的都是二元操作符。
1. 左移( << )
a << b 表示将数值 a 的二进制数值从 0 位算起到第 b - 1 位,整体向左方向移动 b 位,符号位不变,低位空出来的位补数值 0。
a << b = a * (2 ^ b)
2. 右移( >> )
a >> b 表示将数值 a 的二进制数值从 0 位算起到第 b - 1 位,整体向右方向移动 b 位,符号位不变,高位空出来的位补数值 0。
***a >> b = a / ( 2 ^ b )***
3. 无符号右移( >>> )
无符号右移运算符>>>和右移运算符>>是一样的,只不过右移时左边是补上符号位,而无符号右移运算符是补上0,也就是说,对于正数移位来说等同于:>>,负数通过此移位运算符能移位成正数。以-733183670>>>8为例来画一下图
4. 位与( & )
与运算时,进行运算的两个数,从最低位到最高位,一一对应。如果某 bit 的两个数值对应的值都是 1,则结果值相应的 bit 就是 1,否则为 0.
|
|
5. 位或( | )
与运算时,进行运算的两个数,从最低位到最高位,一一对应。如果某 bit 的两个数值对应的值只要 1 个为 1,则结果值相应的 bit 就是 1,否则为 0。
|
|
6. 位异或( ^ )
两个操作数进行异或时,对于同一位上,如果数值相同则为 0,数值不同则为 1。
|
|
7. 位非( ~ )
对操作数的每一位进行操作,1 变成 0,0 变成 1。