微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

左右算术移位后,Java方法返回错误值

如何解决左右算术移位后,Java方法返回错误值

我有一个看起来像这样的方法

private short getAddress(short ir) { //performs bit shifting to isolate and find address
        short addr = ir;
        addr = (short) (addr << 11); //remove leading bits
        if (debug == true) {
            System.out.println("LeftSh Reads " + Integer.toBinaryString(addr));
            debugging();
        }
        addr = (short) Math.abs((addr >> 11)); //Shift back to starting position. Java's casting leaves this in negative for some reason. Taking the absolute value fixes it.
        if (debug == true) {
            System.out.println("RightSh Reads " + Integer.toBinaryString(addr));
            debugging();
        }
        return addr;
    }

在此示例中,短ir = 1557。

addr的预期返回值为21,但是我得到的是11。 我的两个sysout的控制台输出为:

LeftSh Reads 11111111111111111010100000000000

RightSh Reads 1011

我自己学习Java,觉得我错过了导致这种情况发生的根本原因,无论是强制转换还是移位。我该如何解决

解决方法

使用逻辑和(而不是向左/向右移位)来避免出现short签名的问题:

short i = 1557;

short i_masked = (short)(i & 0x001F);

或者,也许更清楚

short i_masked = (short) (i & 0b0000000000011111);

要了解您的代码中发生了什么,我建议您在右移之后但在之前应用abs()打印出该值。

,

当您向右移动时,由于数字的二进制补码,因此得到-11。

取绝对值,则得到11。

要获得预期的21,您需要在左移后执行以下操作。

addr = (short) ((addr&0xFFFF) >>> 11);
  • 这掩盖了左移短线的16位。
  • 然后使用>>>向右移动符号。
System.out.println(addr);

打印

21
,

问题在于short是带符号的数据类型。最高位等于1的值表示负值:

  • 大小转换,例如从shortint的符号扩展负值,这意味着将1的16位添加到负{{1}的前面}值。

  • 算术右移,对于负值,在移位后的模式前插入1位。

让我们通过您的代码输入1557(0x0615 = 0000 0110 0001 0101):

short

正如其他人已经回答的那样,请使用按位And代替移位。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。