0

I am experiencing some weird unsigned right shift operation producing wrong results when trying to perform them on hard-coded and not hard-coded data on Java 8.

I am trying to perform a unsigned right shift on a signed byte 0xBF. If I simply assigned the signed byte to a variable and then use the variable to perform an unsigned right shift operation, I end up getting 0xDF. If I hard-code the 0xBF into the unsigned right shift operation, I get 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}));

The output from the above Java call.

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

How should I solve the above problem ?

thotheolh
  • 7,040
  • 7
  • 33
  • 49
  • "unsigned right shift" in Java is a bit of a misnomer. The value shifted is still signed, but the sign bit is shifted and replaced with zero. So, it makes a difference if you shift a `byte` vs an `int`, since the sign bit is in a different place. – davmac Aug 13 '16 at 10:23

1 Answers1

0

In case of rotated byte you are doing the operation on byte type. In case of signRemoved you are doing the operation on int type and after the operation is done you cast it to byte. Therefore the result is different.

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
Viktor K.
  • 2,670
  • 2
  • 19
  • 30
  • How do I get 0xBF from byte type to 0x5F as byte type without needing to use integer ? – thotheolh Aug 13 '16 at 10:17
  • When using shifting operators, bytes are always first converted to ints, because shifting operators work on ints in java. This explains it well http://stackoverflow.com/questions/3948220/behaviour-of-unsigned-right-shift-applied-to-byte-variable – Viktor K. Aug 13 '16 at 10:31