'Switching the first 4 bits of a byte and the last half
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 :)
Solution 1:[1]
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.
Solution 2:[2]
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;
Solution 3:[3]
I don't want
1111 1001
but0000 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;
}
Solution 4:[4]
static int swapBits(int a) {
// ???????? ??????? ???? ?
int right = (a & 0b00001111);
right= (right<<4);
int left = (a & 0b11110000);
left = (left>>4);
return (right | left);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Akash Srivastav |
Solution 3 | |
Solution 4 | Leonardo Alves Machado |