Java位运算符(位逻辑运算符+位移运算符)
Java 语言中的位运算符分为两大类:位逻辑运算符和位移运算符。
位运算符如下表所示:
下面分别对位逻辑运算符和位移运算符予以介绍。
参照上表来看一下这 4 个运算符的实际运算过程。
例如,12 和 8经过位逻辑与运算后得到的结果是 8。
例如,4 和 8 经过位逻辑或运算后的结果是 12:
例如,31 和 22 经过位逻辑异或运算后得到的结果是 9:
例如,123 经过位逻辑取反运算后得到的结果是 -124:
&、| 和 ^ 也可以用于逻辑运算,运算结果如下表所示。
【实例】
在介绍位移运算符前,先来学习下什么是二进制数。
所谓二进制数,是指用 0 和 1 来表示的数。例如,十进制数 42 的二进制表示形式为 101010。那么,十进制数如何转换为二进制数呢?以十进制数 42 为例,将十进制数 42 转换成二进制数的过程如下图所示。
图 1 将十进制数42转换成二进制数
因为计算机内部表示数的字节单位是定长的,例如 8 位、16 位或 32 位,所以当二进制数的位数不够时,须在高位补零。十进制数 42 的二进制表示形式为 101010,如果计算机的字长是 8 位,那么 101010 的规范写法为 0010 1010。
如果把十进制数 −42 转换成二进制数,过程又是怎样的呢?先将对应的正整数转换成二进制数,再对二进制数取反,最后对结果加一,具体的转换过程如下图所示。
图 2 将十进制数-42转换成二进制数
综上所述,十进制数 −42 的二进制表示形式为 1101 0110。
掌握“什么是二进制数”和“十进制数是如何转换为二进制数的”这两个内容后,再来学习下左移、右移和无符号右移这3种运算。
图 3 左移运算
例如,short 型整数 9115 的二进制形式是 0010 0011 1001 1011,左移一位变成 18230,左移两位变成 36460,如下图所示。
图 4 左移运算过程
图 5 右移运算
例如,short 型整数 9115 的二进制形式是 0010 0011 1001 1011,右移一位变成 4557,右移两位变成 2278,运算过程如下图所示。
图 6 正数右移运算过程
short 型整数 -32766 的二进制形式是 0010 0011 1001 1011,右移一位变成 -16383,右移两位变成 -8192,运算过程如下图所示。
图 7 负数右移运算过程
例如 int 型整数 -32766 的二进制形式是 1111 1111 1111 1111 1000 0000 0000 0010,右移一位变成 2147467265,右移两位变成 1073733632,运算过程如下图所示。
图 8 无符号右移运算过程
【实例】使用位移运算符对变量进行位移运算
位运算符如下表所示:
运算符 | 含义 | 举例 |
---|---|---|
& | 与 | a & b |
| | 或 | a | b |
~ | 取反 | ~a |
^ | 异或 | a ^ b |
<< | 左移位 | a << 2 |
>> | 右移位 | b >> 4 |
>>> | 无符号右移位 | x >>> 2 |
下面分别对位逻辑运算符和位移运算符予以介绍。
位逻辑运算符
位逻辑运算符包括 &、|、^ 和 ~,其运算结果如下表所示。A | B | A & B | A | B | A^B | ~A |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
参照上表来看一下这 4 个运算符的实际运算过程。
1)位逻辑与
实际上是将操作数转换成二进制表示方式,然后将两个二进制操作数对象从低位(最右边)到高位对齐,每位求与。若两个操作数对象同一位都为 1,则结果对应位为 1;否则结果对应位为 0。例如,12 和 8经过位逻辑与运算后得到的结果是 8。
0000 0000 0000 1100 (十进制数12的原码表示) & 0000 0000 0000 1000 (十进制数8的原码表示) 0000 0000 0000 1000 (十进制数8的原码表示)
2) 位逻辑或
实际上是将操作数转换成二进制表示方式,然后将两个二进制操作数对象从低位(最右边)到高位对齐,每位求或。若两个操作数对象同一位都为 0,则结果对应位为 0;否则结果对应位为 1。例如,4 和 8 经过位逻辑或运算后的结果是 12:
0000 0000 0000 0100 (十进制数4的原码表示) | 0000 0000 0000 1000 (十进制数8的原码表示) 0000 0000 0000 1100 (十进制数12的原码表示)
3) 位逻辑异或
实际上是将操作数转换成二进制表示方式,然后将两个二进制操作数对象从低位(最右边)到高位对齐,每位求异或。若两个操作数对象同一位不同,则结果对应位为 1;否则结果对应位为 0。例如,31 和 22 经过位逻辑异或运算后得到的结果是 9:
0000 0000 0001 1111 (十进制数31的原码表示) ^ 0000 0000 0001 0110 (十进制数22的原码表示) 0000 0000 0000 1001 (十进制数9的原码表示)
4) 位逻辑取反
实际上是将操作数转换成二进制表示方式,然后将各位二进制位由 1 变为 0,由 0 变为 1。例如,123 经过位逻辑取反运算后得到的结果是 -124:
~ 0000 0000 0111 1011 (十进制数123的原码表示) 1111 1111 1000 0100 (十进制数−124的原码表示)
&、| 和 ^ 也可以用于逻辑运算,运算结果如下表所示。
A | B | A & B | A | B | A ^ B |
---|---|---|---|---|
true | true | true | true | false |
true | false | false | true | true |
false | true | false | true | true |
false | false | false | false | false |
public class BitwiseAnd { public static void main(String[] args) { int a = 12; // 二进制: 1100 int b = 7; // 二进制: 0111 int result = a & b; // 按位与的结果为 0100,即4 System.out.println("按位与的结果: " + result); } }运行结果为:
按位与的结果: 4
实例中,我们对整数 a 和 b 进行按位与操作,比较每一位,只有当两位都为 1 时,结果位才为 1。位移运算符
位移运算符有 3 个,分别是左移运算符 <<、右移运算符 >> 和无符号右移运算符 >>>。在介绍位移运算符前,先来学习下什么是二进制数。
所谓二进制数,是指用 0 和 1 来表示的数。例如,十进制数 42 的二进制表示形式为 101010。那么,十进制数如何转换为二进制数呢?以十进制数 42 为例,将十进制数 42 转换成二进制数的过程如下图所示。
图 1 将十进制数42转换成二进制数
因为计算机内部表示数的字节单位是定长的,例如 8 位、16 位或 32 位,所以当二进制数的位数不够时,须在高位补零。十进制数 42 的二进制表示形式为 101010,如果计算机的字长是 8 位,那么 101010 的规范写法为 0010 1010。
如果把十进制数 −42 转换成二进制数,过程又是怎样的呢?先将对应的正整数转换成二进制数,再对二进制数取反,最后对结果加一,具体的转换过程如下图所示。
图 2 将十进制数-42转换成二进制数
综上所述,十进制数 −42 的二进制表示形式为 1101 0110。
掌握“什么是二进制数”和“十进制数是如何转换为二进制数的”这两个内容后,再来学习下左移、右移和无符号右移这3种运算。
1) 左移运算
左移运算是将一个二进制操作数对象按指定的位数向左移,左边(高位端)溢出的位被丢弃,右边(低位端)的空位用 0 补充。左移 n 位相当于乘以 2n,如下图所示。图 3 左移运算
例如,short 型整数 9115 的二进制形式是 0010 0011 1001 1011,左移一位变成 18230,左移两位变成 36460,如下图所示。
图 4 左移运算过程
2) 右移运算
右移运算是将一个二进制数按指定的位数向右移动,右边(低位端)溢出的位被丢弃,左边(高位端)用符号位补充,正数的符号位为 0,负数的符号位为 1。右移 n 位相当于除以 2n,如下图所示。图 5 右移运算
例如,short 型整数 9115 的二进制形式是 0010 0011 1001 1011,右移一位变成 4557,右移两位变成 2278,运算过程如下图所示。
图 6 正数右移运算过程
short 型整数 -32766 的二进制形式是 0010 0011 1001 1011,右移一位变成 -16383,右移两位变成 -8192,运算过程如下图所示。
图 7 负数右移运算过程
3) 无符号右移运算
无符号右移运算是将一个二进制的数按指定的位数向右移动,右边(低位端)溢出的位被丢弃,左边(高位端)一律用 0 填充,相当于除以 2 的幂。例如 int 型整数 -32766 的二进制形式是 1111 1111 1111 1111 1000 0000 0000 0010,右移一位变成 2147467265,右移两位变成 1073733632,运算过程如下图所示。
图 8 无符号右移运算过程
【实例】使用位移运算符对变量进行位移运算
public class BitwiseShiftExample { public static void main(String[] args) { int number = 10; // 二进制表示为 1010 int shift = 2; // 将数字左移2位 // 左移操作后,二进制表示为 101000,即 40 int result = number << shift; System.out.println("原始数字: " + number); System.out.println("左移 " + shift + " 位后的结果: " + result); } }运行结果为:
原始数字: 10
左移 2 位后的结果: 40