Java 移位运算符

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值