Java基础填坑日志(1)——移位运算符

问题描述

最近在学习神书《Java编程思想》(第4版),在学习到第三章移位运算符的时候,讲解里面有这么一段话,一开始让我百思不得其解:

Java 也添加了一种“无符号”右移位运算符( >>>), 它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是 C 或 C++没有的。若对 char,byte 或者 short 进行移位处理,那么在移位进行之前,它们会自动转换成一个 int。只有右侧的5个低位才会用到。这样可防止我们在一个 int 数里移动不切实际的位数。若对一个 long 值进行处理,最后得到的结果也是 long。此时只会用到右侧的 6 个低位,防止移动超过 long 值里现成的位数。但在进行“无符号”右移位时,也可能遇到一个问题。若对 byte 或 short 值进行右移位运算,得到的可能不是正确的结果( Java 1.0 和 Java 1.1 特别突出)。它们会自动转换成 int 类型,并进行右移位。但“零扩展”不会发生,所以在那些情况下会得到-1 的结果。

于是我用书上的例程做了一下编程实践:

//: URShift.java
// Test of unsigned right shift
package c03;

public class URShift {
    public static void main(String[] args) {
        int i = -1;
        i >>>= 10;
        System.out.println(i);
        long l = -1;
        l >>>= 10;
        System.out.println(l);
        short s = -1;
        s >>>= 10;
        System.out.println(s);
        byte b = -1;
        b >>>= 10;
        System.out.println(b);
    }
} ///:~

程序运行结果如下:

4194303
18014398509481983
-1
-1

到这里我还是有点迷惘,还是不理解为啥会出现上面的结果,然后我改了一下代码进行测试:

byte b = -1;
b >>>= 24;
System.out.println(b);

输出-1,继续修改代码:

byte b = -1;
b >>>= 25;
System.out.println(b);

输出127,再思考上面书中的内容,恍然大悟。

分析

出现上述输出的原因是,在byteshort类型进行移位运算的时候会首先被转换为int类型,以byte为例:

byte b = -1;
b:11111111 (-1)
(int)b:11111111 11111111 11111111 11111111
(int)b>>>10:0000000 00111111 11111111 11111111
b:11111111 (-1)

所以问题产生的根本原因还是在转换成int类型后移位造成的。

byte b = -1;
b:11111111 (-1)
(int)b:11111111 11111111 11111111 11111111
(int)b >>> 25:0000000 00000000 00000000 01111111
b:01111111 (127)

顺便说一句,int类型转换为byte类型是会截取其低8位,丢弃高24位,得到的数值可能是错误的,但是byte转换为int则没有这个问题,因为是低精度向高精度转换,不会损失精度。

疑问

书里的这段话我还是不知道是什么意思(也许是中文翻译的问题),求各路大神解答:

只有右侧的5个低位才会用到。这样可防止我们在一个 int 数里移动不切实际的位数。若对一个 long 值进行处理,最后得到的结果也是 long。此时只会用到右侧的 6 个低位,防止移动超过 long 值里现成的位数。

注意: 移位运算符的右操作数要完成模 32 的运算(除非左操作数是long 类型, 在这种情况下需要对右操作数模64 )。 例如, 1 << 35 的值等同于1 << 38

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值