
3.3.2 移位运算

移位运算按照规则将二进制数的每一位向左或向右移动,从而改变数值大小。Java语言提供了3个移位运算的运算符,即移位运算符,如表3.9所示。
表3.9 移位运算符

1.左移运算
左移运算使用左移运算符(<<)将二进制数的每一位向左移动指定位数。使用左移运算符构建的表达式被称为左移运算表达式。其语法形式如下:

左移运算表达式需要两个操作数,因此左移运算符是二元运算符(双目运算符)。左移分为无符号整型左移和有符号整型左移。下面将详细讲解这两种左移方式。
(1)无符号整型左移:将一个二进制数的每一位向左移动指定的位数,其中左边被移出整型存储边界的位直接抛弃,右边空白的位用0填补。如图3.20所示为无符号整型二进制数00001111左移4位的过程。

图3.20 无符号整型左移
注意:左移1位的效果相当于将一个整数乘以一个因子为2的整数。向左移动一个整数的比特位相当于将这个数乘以2。以下算式展示的就是将整数15的位向左移动4位的结果。

【示例3-25】下面将二进制数00001111向左移动4位。代码如下:

运行结果如下:

(2)有符号整型左移:有符号整型通过二进制位的第一位来表示,第一位为0表示正数,为1表示负数。其余的位(称为数值位)用来存储实值。有符号正数和无符号正数在计算机中存储的结果是一样的。如图3.21所示为+4的二进制存储。

图3.21 +4的二进制存储
负数的存储(二进制存储)比较复杂,这里需要有一个运算,即2的n次方减去负数的绝对值,其中n为数值位的位数。例如-4,它以byte类型存储时有7位数值位,所以它的二进制存储等同于

再将124转化为二进制数,就是-4的二进制存储,如图3.22所示。

图3.22 -4的二进制存储
除了可以使用2的n次方减去负数的绝对值这个方法计算负数的二进制存储外,还可以使用取反加1的方法(补码)实现负数的二进制存储。还是以-4为例,首先,获取4的原码,即00000100,然后进行取反,如图3.23所示。

图3.23 原码取反
最后将取反的值加1,如图3.24所示。

图3.24 取反值加1
得到的11111100为-4的二进制存储。了解了正数和负数的表示后,再来看有符号整型左移,对于一个正数来说,其左移就是无符号整型左移,对于一个负数来说,后面的运算一样,即左移1位乘以2。
【示例3-26】下面将-4向左移动1位。代码如下:


运行结果如下:

2.右移运算
右移运算使用右移运算符(>>)将二进制数的每一位向右移动指定位数。使用右移运算符构建的表达式被称为右移运算表达式。其语法形式如下:

右移运算表达式需要两个操作数,因此右移运算符是二元运算符(双目运算符)。右移分为无符号整型右移和有符号整型右移。下面将详细讲解这两种右移方式。
(1)无符号整型右移:将一个二进制数的每一位向右移动指定的位数,其中右边被移出整型存储边界的位直接抛弃,左边空白的位用0填补。如图3.25所示为无符号整型二进制数00001111右移2位的过程。

图3.25 无符号整型右移
注意:右移1位的效果相当于将一个整数除以一个因子为2的整数。向右移动一个整数的比特位相当于将这个数除以2。以下算式展示的就是将整数15的位向右移动2位的结果:

【示例3-27】下面将15右移2位。代码如下:

运行结果如下:

(2)有符号整型右移:如果是正数,其右移和无符号整型右移是一样的,但是对于负数来说是有分别的,它需要使用符号位去填充空白位。如图3.26所示为将-4向右移动1位的操作。

图3.26 有符号整型右移
【示例3-28】下面将-4右移1位。代码如下:

运行结果如下:

3.逻辑右移运算
逻辑右移运算需要使用逻辑右移运算符(>>>)。使用逻辑右移运算符构建的表达式被称为逻辑右移运算表达式。其语法形式如下:

逻辑右移运算符需要两个操作数,因此它是二元运算符(双目运算符)。逻辑右移是无符号右移,忽略符号位,空位都以0补齐。
【示例3-29】下面将15逻辑右移2位。代码如下:

运行结果如下:
