Inverse byte shift operation

I have this code

byte[] b = new byte[]{-33,-4,20,30}; System.err.println(Arrays.toString(b)); int x = (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]; b = new byte[]{(byte)(x >> 24), (byte)(x >> 16), (byte)(x >> 8), (byte)(x)}; System.err.println(Arrays.toString(b)); 

Output:

 [-33, -4, 20, 30] [-34, -4, 20, 30] 

I cannot understand why these operations are not inversions.

+4
source share
2 answers

Your problem is the unwanted extension of the character.

In particular, b[1] is -4 or 0xfc , which stands for 0xfffffffc , and then shifted to the left to 0xfffc0000 . This reduces the low byte by 1.

Try:

 int x = ((b[0] & 0xff) << 24) + ((b[1] & 0xff) << 16) + ((b[2] & 0xff) << 8) + (b[3] & 0xff); 
+6
source

Please ignore my previous answer; this is completely wrong.

I think the problem here is that when you compose bits this way:

 (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3] 

You do not do what you think you do. In particular, suppose that b[1] negative (which is). When Java performs bit shifts, it always increments to int before performing the shift. This means that b[1] will look like this:

 11111111 11111111 11111111 bbbbbbbb 

Here, the leading 1s are taken from a signed two-digit representation of integers, which makes negative numbers represented by a set of leading zeros. When you change this number, you get

 11111111 bbbbbbbb 00000000 00000000 

If you add these bits to (b[0] << 24) , which has the form

 aaaaaaaa 00000000 00000000 00000000 

You do not get

 aaaaaaaa bbbbbbbb 00000000 00000000 

Due to the leading 1s in view. To fix this, you need to mask the sign bits before performing the addition. In particular, if you change

 b[1] << 16 

to

 (b[1] << 16) & 0x00FFFFFF 

Then you mask the bits to get

 00000000 bbbbbbbb 00000000 00000000 

So now, when you add two values, you get

 aaaaaaaa bbbbbbbb 00000000 00000000 

Optional.

The correct expression for composing the bits is thus formed using ANDing in the corresponding masks at the corresponding time points:

 (b[0] << 24) + ((b[1] << 16) & 0x00FFFFFF) + ((b[2] << 8) & 0x0000FFFF) + (b[3] & 0x000000FF) 

I tested this on my system and it seems to work fine.

Hope this helps!

+3
source

Source: https://habr.com/ru/post/1383963/


All Articles