如何解决左右算术移位后,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的值表示负值:
-
大小转换,例如从
short
到int
的符号扩展负值,这意味着将1
的16位添加到负{{1}的前面}值。 -
算术右移,对于负值,在移位后的模式前插入1位。
让我们通过您的代码输入1557(0x0615 = 0000 0110 0001 0101):
short
正如其他人已经回答的那样,请使用按位And代替移位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。