Switching the first 4 bits of a byte and the last half

Viewed 848

I need to switch the first half and the second half of a byte: Make 0011 0101 to 0101 0011 for example

I thought it might work this way: For example, i have 1001 1100 i bitshift to the left 4 times and get 1111 1001(because if the first bit is a 1 the others become a one too) i bitshift to the right 4 times and get 1100 0000(the second half of the byte gets filled with 0s) i don't want 1111 1001 but 0000 1001 so i do 0x00001111 & 1111 1001 (which filters the frist 4 bits) to make 1111 1001 to 0000 1001 then i add everything up:

0000 1001 + 1100 0000 = 1100 1001

I got this:

bytes[i] = (byte) (( 0x00001111 & (bytes[i] >> 4)) + (bytes[i] << 4) );

here is one output: 11111111 to 00000001

I do not really understand why this is happening, I know the binary System and I think I know how bitshifting works but I can't explain this one. Sorry for bad english :)

4 Answers

Be careful with the >>> operation, which shifts the sign bits without sign extending so zero bits will fill in on the left. The problem is that it is an integer operation. The >> works the same way except it sign extends thru the int.

  int i = -1;
  i >>>= 30;
  System.out.println(i); // prints 3 as expected.

  byte b = -1;
  b >>>= 6;
  System.out.printnln(b); // prints -1 ???

The byte is still -1 because byte b = -1 was shifted as though it was an int then reassigned to a byte. So the byte remained negative. To get 3, you would need to do something that seems strange, like the following.

   byte b = -1;
   b >>>=30;
   System.out.println(b); // prints 3

So to do your swap you need to do the following;


   byte b = 0b10100110;
   b = (byte)(((b>>>4)&0xF)|(b<<4));

The 0xF mask, masks off those lingering high order bits left over from the conversion from integer back to byte.

I'm not sure about the syntax for bit manipulation in Java, although here's how you can do it.

bitmask = 0x1111;
firstHalf = ((bytes[i] >> 4) & bitmask);
secondHalf = ((bytes[i] & bitmask) << 4)
result = firstHalf | secondHalf;

I don't want 1111 1001 but 0000 1001

If so, you need to use shift right zero fill operator(>>>) instead of preserving sign of the number.

I don't think the formula found works properly.

 public byte reverseBitsByte(byte x) {
  int intSize = 8;
  byte y=0;
  for(int position=intSize-1; position>0; position--){
    y+=((x&1)<<position);
    x >>= 1;
  }
  return y;
}
static int swapBits(int a)  {
    // Написать решение сюда ↓
    int right = (a & 0b00001111);
    right= (right<<4);
    int left = (a & 0b11110000);
    left = (left>>4);
    return (right | left);
}
Related