【问题标题】:Unsigned Right Shift on Signed Bytes producing errors有符号字节上的无符号右移产生错误
【发布时间】:2016-08-13 10:03:39
【问题描述】:

当我尝试对 Java 8 上的硬编码和非硬编码数据执行这些操作时,我遇到了一些奇怪的无符号右移操作,产生了错误的结果。

我正在尝试对有符号字节 0xBF 执行无符号右移。如果我只是将有符号字节分配给一个变量,然后使用该变量执行无符号右移操作,我最终会得到0xDF。如果我将 0xBF 硬编码到无符号右移操作中,我会得到 0x5F

byte originalByte = (byte) 0xBF;
System.out.println("Original Data: " + toHexString(new byte[]{originalByte}));

byte rotatedByte = (byte) (originalByte >>> 1);
System.out.println("Rotated Data: " + toHexString(new byte[]{rotatedByte}));

byte signRemoved = (byte) (0xBF >>> 1);
System.out.println("Sign Removed Data: " + toHexString(new byte[]{signRemoved}));

上述 Java 调用的输出。

Original Data: BF
Rotated Data: DF
Sign Removed Data: 5F

我应该如何解决上述问题?

【问题讨论】:

  • Java 中的“无符号右移”有点用词不当。移位的值仍然是有符号的,但符号位被移位并替换为零。因此,如果您将 byteint 进行移位,则会有所不同,因为符号位位于不同的位置。

标签: java bit-shift unsigned


【解决方案1】:

在旋转字节的情况下,您正在对字节类型进行操作。在 signRemoved 的情况下,您正在对 int 类型进行操作,并且在操作完成后将其转换为字节。所以结果不一样。

int i = 0xBF; // this is int and the value is 191
byte b = (byte) 0xBF; // this is byte and value is -65 

int i2 = (i >>> 1) //here the operation is done on int result is 95
byte b2 = (byte) i2 // result stays 95

int i3 = b >>> 1 // here b is first promoted to int (-65) then  after right shift it becomes 2147483615
byte b3 = (byte) i3 // -33

【讨论】:

  • 如何在不需要使用整数的情况下将 0xBF 从字节类型转换为 0x5F 作为字节类型?
  • 当使用移位操作符时,字节总是首先转换为整数,因为移位操作符在java中作用于整数。这很好解释stackoverflow.com/questions/3948220/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 2020-12-28
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多