Java 中有三种移位运算符,分别是:
<<:左移运算符>>:带符号右移>>>:无符号右移
那么这个移位运算符该怎么理解呢?顾名思义,移位移位,就是移动位置。那么问题来了,既然是移动位置,那么移位运算符移动的是谁的位置,怎么移?我们写个程序测试一下。
public class Main {
public static void main(String[] args) {
System.out.println("----------- 初始值 -----------");
int number = 10;
System.out.println("十进制:" + number + "\t二进制:" + Integer.toBinaryString(number));
leftShift(number);
rightShift(number);
unsignedRightShift(number);
}
public static void leftShift(int number) {
System.out.println("----------- 左移 -----------");
number = number << 1;
System.out.println("十进制:" + number + "\t二进制:" + Integer.toBinaryString(number));
}
public static void rightShift(int number) {
System.out.println("----------- 带符号右移 -----------");
number = number >> 1;
System.out.println("十进制:" + number + "\t二进制:" + Integer.toBinaryString(number));
}
public static void unsignedRightShift(int number) {
System.out.println("----------- 无符号右移 -----------");
number = number >>> 1;
System.out.println("十进制:" + number + "\t二进制:" + Integer.toBinaryString(number));
}
}
上述程序执行后的结果如下:
----------- 初始值 -----------
十进制:10 二进制:1010
----------- 左移 -----------
十进制:20 二进制:10100
----------- 带符号右移 -----------
十进制:5 二进制:101
----------- 无符号右移 -----------
十进制:5 二进制:101
观察结果我们发现,实际上移位运算符移动的是二进制数值的位置。
以上述结果数据为例,初始值 10 的二进制为 1010,使用 10 << 1 向左移动一位后,即整串 1010 向左移动,然后在右端补 0,最后结果即为 10100。
但是,右移就显得复杂了些。我们注意到,Java 中右移分为带符号右移和无符号右移,那么两者有什么区别呢?
带符号右移在向右移位后,会在左侧补上原最高位的值。
无符号右移在向右移位后,会在左侧补上直接补上 0。
在上面的例子里,由于初始值 10 的二进制最高位为 0,所以无论是使用带符号右移还是无符号右移,二进制 1010 都会向右移动一位,然后在左端补 0,最后结果即为 101。
我们现在换个初始值,使其二进制首位为 1,即可观察到带符号右移和无符号右移的差异。
假设初始值为 -10,运行上面的程序,得到以下结果:
----------- 初始值 -----------
十进制:-10 二进制:11111111111111111111111111110110
----------- 左移 -----------
十进制:-20 二进制:11111111111111111111111111101100
----------- 带符号右移 -----------
十进制:-5 二进制:11111111111111111111111111111011
----------- 无符号右移 -----------
十进制:2147483643 二进制:1111111111111111111111111111011
乍一看好像没什么区别,但是把右移后的二进制值复制到一起,会发现有趣的事。
11111111111111111111111111111011
1111111111111111111111111111011
我们发现,无符号右移后的二进制值少了一位。实际上是由于 toBinaryString 没有把二进制前的 0 打印出来而已,我们现在把这个 0 补上,再比较一下。
11111111111111111111111111111011
01111111111111111111111111111011
确实如上面所说,带符号右移和无符号右移的区别就在于右移后左侧是补 0 还是补最高位的值。
现在,我们可以对上面所述内容做个总结:
<<:表示左移运算符,作用是将二进制数左移 N 位,并在右侧补齐0>>:表示带符号右移,作用是将二进制数右移 N 位,并在左侧补齐最高位对应的值>>>:表示无符号右移,作用是将二进制数右移 N 位,并在左侧补齐0
本文深入解析Java中的三种移位运算符:左移(<<)、带符号右移(>>)和无符号右移(>>>)。通过实例演示了这些运算符如何操作二进制数,以及它们在处理正负数时的不同行为。
1万+

被折叠的 条评论
为什么被折叠?



