word color;
crap = ((color & 0xffc0) >> 1) | (color & 0x1f)
I have this shifting code. I have no idea what the purpose is of this code, but I suspect it has something to do with switching between 555 to 565 colors.
How would I create a function that does the exact opposite as the code above? That converts the variable back to the original color number?
You can't. "And" (&) and "or" (|) don't have an inverse (neither does bit shifting if you overflow). Meaning that there could be multiple values of color that could turn into crap.
I suspect it has something to do with switching between 555 to 565 colors.
Yes, that's what it's doing. color will be the 565 representation, and crap the corresponding 555 representation.
Lets look at what each operation does. I'll refer to the three fields as a (5 bits), b (6 bits, transformed to 5) and c (5 bits).
(color & 0xffc0) clears the bottom 6 bits of the word, removing c and the least significant bit of b, preserving a and the most significant 5 bits of b.
>> 1 shifts these bits right, so we now have a (5 bits), b (5 bits), and an empty 5-bit field.
(color & 0x1f) clears all the bits except for the bottom 5 bits - that is, it preserves 'c' and removes the other fields.
Finally, | combines the two values, giving a and b from the left-hand side, and c from the right-hand side, each in 5 bits.
How would I create a function that does the exact opposite as the code above? That converts the variable back to the original color number?
color = ((crap & 0xffe0) << 1) | (crap & 0x1f);
Note that the least significant bit of b is now zero, whatever it was to start with. That information was lost in the first transformation, and can't be recovered.
Strictly speaking, you can't, since the transformation irreversibly deletes the fifth least significant bit of color (it does preserve all the other bits).
Assuming the fifth bit didn't contain any useful data to begin with, the following will give you the inverse of your transformation:
color = ((crap & 0xffe0) << 1 | (crap & 0x1f))
Again, this restores color except for the fifth bit, which has been lost.
Yes, this looks like it converts from 565 RGB to 555 RGB by discaring the lowest bit of G.
You're losing one bit, so you can't invert it exactly (the lowest bit of G is just gone), but you can approximate the inverse by doing something like this:
color = ((crap & 0xffe0) << 1) | (crap & 0x1f)
The first part, ((crap & 0xffe0) << 1) is just masking out the R and G components and shifting them back up. The last part, | (crap & 0x1f), is masking out the blue and adding it back into the result.
Related
I have a 32 bits integer that I treat as a bitfield. I'm interested in the value of the bits with an index of the form 3n where n range from 0 to 6 (every third bit between 0 and 18) I'm not interested in the bits with index in the form 3n+1 or 3n+2.
I can easily use the bitwise AND operator to keep the bits i'm interested in and set all the others bits to zero.
I would also need to "pack" the bits I'm interested in in the 7 least significant bits positions. So the bit at position 0 stay at 0, but the bit at position 3 is moved to position 1, the bit at position 6 moves to position 2 and so on.
I would like to do this in an efficient way, ideally without using a loop. Is there a combinations of operations I could apply to an integer to achieve this?
Since we're only talking about integer arithmetics here, I don't think the programming language I plan to use is of importance. But if you need to know :
I'm gonna use JavaScript.
If the order of the bits is not important, they can be packed into bits 0-6 like this:
function packbits(a)
{
// mask out the bits we're not interested in:
var b = a & 299593; // 1001001001001001001 in binary
// pack into the lower 7 bits:
return (b | (b >> 8) | (b >> 13)) & 127;
}
If the initial bit ordering is like this:
bit 31 bit 0
xxxxxxxxxxxxxGxxFxxExxDxxCxxBxxA
Then the packed ordering is like this:
bit 7 bit 0
0CGEBFDA
I am creating a chess program and for the board representation I am using bitboards. The bitboard for white pawns looks like this:
whitePawns=0x000000000000FF00;
Now, if I want to move the white pawn on the square D4, I would have to shift the 12th bit by either 8 or 10 places so that it can get on to the next rank. I want to shift the 12th bit without disturbing the positions of the remaining bits. How do I do that?
After shifting the whitePawns variable should look this:
whitePawns=0x0000000008F700;
Rather than shifting the bit, you can remove 1 from the old position, and put it in the new position.
For example, if you know that the bit at position 5 is set, and the bit at position 12 is not set, and you want to shift the fifth bit to the 12-th position, you can do it with a single XOR:
whitePawns ^= ((1 << 5) | (1 << 12));
The way this works is that XOR-ing a value with a mask "flips" all bits of the value marked by 1s in the mask. In this case, the mask is constructed to have 1s in positions 5 and 12. When you XOR it with the positions, the 1 in fifth position becomes zero, and zero in the 12-th position becomes 1.
I think you don't want a shift, you want to swap to bits. Try turning bit A off and then turning bit B on. Something like this:
whitePawns &= ~(1 << A); // Turn bit A off
whitePawns |= (1 << B); // Turn bit B on
Where A and B are the positions of the bits you want to swap.
EDIT: Whether the move is valid or not is another story, make the move only if bit B is NOT set (and probably other conditions):
if (!(whitePawns & (1 << B))) {
// Make the swap.
}
I don't understand what this code is doing at all, could someone please explain it?
long input; //just here to show the type, assume it has a value stored
unsigned int output( input >> 4 & 0x0F );
Thanks
bitshifts the input 4 bits to the right, then masks by the lower 4 bits.
Take this example 16 bit number: (the dots are just for visual separation)
1001.1111.1101.1001 >> 4 = 0000.1001.1111.1101
0000.1001.1111.1101 & 0x0F = 1101 (or 0000.0000.0000.1101 to be more explicit)
& is the bitwise AND operator. "& 0x0F" is sometimes done to pad the first 4 bits with 0s, or ignore the first(leftmost) 4 bits in a value.
0x0f = 00001111. So a bitwise & operation of 0x0f with any other bit pattern will retain only the rightmost 4 bits, clearing the left 4 bits.
If the input has a value of 01010001, after doing &0x0F, we'll get 00000001 - which is a pattern we get after clearing the left 4 bits.
Just as another example, this is a code I've used in a project:
Byte verflag = (Byte)(bIsAck & 0x0f) | ((version << 4) & 0xf0). Here I'm combining two values into a single Byte value to save space because it's being used in a packet header structure. bIsAck is a BOOL and version is a Byte whose value is very small. So both these values can be contained in a single Byte variable.
The first nibble in the resultant variable will contain the value of version and the second nibble will contain the value of bIsAck. I can retrieve the values into separate variables at the receiving by doing a 4 bits >> while taking the value of version.
Hope this is somewhere near to what you asked for.
That is doing a bitwise right shift the contents of "input" by 4 bits, then doing a bitwise AND of the result with 0x0F (1101).
What it does depends on the contents and type of "input". Is it an int? A long? A string (which would mean the shift and bitwise AND are being done on a pointer to the first byte).
Google for "c++ bitwise operations" for more details on what's going on under the hood.
Additionally, look at C++ operator precedence because the C/C++ precedence is not exactly the same as in many other languages.
I am trying to understand how to use Bitwise AND to extract the values of individual bytes.
What I have is a 4-byte array and am casting the last 2 bytes into a single 2 byte value. Then I am trying to extract the original single byte values from that 2 byte value. See the attachment for a screen shot of my code and values.
The problem I am having is I am not able to get the value of the last byte in the 2 byte value.
How would I go about doing this with Bitwise AND?
The problem I am having is I am not able to get the value of the last byte in the 2 byte value.
Your 2byte integer is formed with the values 3 and 4 (since your pointer is to a[1]). As you have already seen in your tests, you can get the 3 by applying the mask 0xFF. Now, to get the 4 you need to remove the lower bits and shift the value. In your example, by using the mask 0xFF00 you effectively remove the 3 from the 16bit number, but you leave the 4 in the high byte of your 2byte number, which is the value 1024 == 2^10 -- 11th bit set, which is the third bit in the second byte (counting from the least representative)
You can shift that result 8 bits to the right to get your 4, or else you can ignore the mask altogether, since by just shifting to the right the lowest bits will disappear:
4 == ( x>>8 )
More interesting results to test bitwise and can be obtained by working with a single number:
int x = 7; // or char, for what matters:
(x & 0x1) == 1;
(x & (0x1<<1) ) == 2; // (x & 0x2)
(x & ~(0x2)) == 5;
You need to add some bit-shifting to convert the masked value from the upper byte to the lower byte.
The problem I am having is I am not able to get the value of the last
byte in the 2 byte value.
Not sure where that "watch" table comes from or if there is more code involved, but it looks to me like the result is correct. Remember, one of them is a high byte and so the value is shifted << 8 places. On a little endian machine, the high byte would be the second one.
I have an arbitrary 8-bit binary number e.g., 11101101
I have to swap all the pair of bits like:
Before swapping: 11-10-11-01
After swapping: 11-01-11-10
I was asked this in an interview !
In pseudo-code:
x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1)
It works by handling the low bits and high bits of each bit-pair separately and then combining the result:
The expression x & 0b10101010 extracts the high bit from each pair, and then >> 1 shifts it to the low bit position.
Similarly the expression (x & 0b01010101) << 1 extracts the low bit from each pair and shifts it to the high bit position.
The two parts are then combined using bitwise-OR.
Since not all languages allow you to write binary literals directly, you could write them in for example hexadecimal:
Binary Hexadecimal Decimal
0b10101010 0xaa 170
0b01010101 0x55 85
Make two bit masks, one containing all the even bits and one containing the uneven bits (10101010 and 01010101).
Use bitwise-and to filter the input into two numbers, one having all the even bits zeroed, the other having all the uneven bits zeroed.
Shift the number that contains only even bits one bit to the left, and the other one one bit to the right
Use bitwise-or to combine them back together.
Example for 16 bits (not actual code):
short swap_bit_pair(short i) {
return ((i & 0101010110101010b) >> 1) | ((i & 0x0101010101010101b) << 1));
}
b = (a & 170 >> 1) | (a & 85 << 1)
The most elegant and flexible solution is, as others have said, to apply an 'comb' mask to both the even and odd bits seperately and then, having shifted them left and right respectively one place to combine them using bitwise or.
One other solution you may want to think about takes advantage of the relatively small size of your datatype. You can create a look up table of 256 values which is statically initialised to the values you want as output to your input:
const unsigned char lookup[] = { 0x02, 0x01, 0x03, 0x08, 0x0A, 0x09, 0x0B ...
Each value is placed in the array to represent the transformation of the index. So if you then do this:
unsigned char out = lookup[ 0xAA ];
out will contain 0x55
This is more cumbersome and less flexible than the first approach (what if you want to move from 8 bits to 16?) but does have the approach that it will be measurably faster if performing a large number of these operations.
Suppose your number is num.
First find the even position bit:
num & oxAAAAAAAA
Second step find the odd position bit:
num & ox55555555
3rd step change position odd position to even position bit and even position bit to odd position bit:
Even = (num & oxAAAAAAAA)>>1
Odd = (num & 0x55555555)<<1
Last step ... result = Even | Odd
Print result
I would first code it 'longhand' - that is to say in several obvious, explicit stages, and use that to validate that the unit tests I had in place were functioning correctly, and then only move to more esoteric bit manipulation solutions if I had a need for performance (and that extra performance was delivered by said improvments)
Code for people first, computers second.