Masking and extracting bits in C
I've looked at the posts about mask but still can't figure out how to extract certain bits from a number in C.
Say, if we have int number 0001 1010 0100 1011
, so what is the hexadecimal representation x1a4b
to the right? If I want to know from 5th to 7th number, which in this case 101
should I use int mask= 0x0000 1110 0000 0000, int extract = mask&number
?
Also how can I check if there is 101
? I guess ==
it won't work here ... Thanks a lot !
source to share
Assuming a gcc extension 0b
to define binary literals:
int number = 0b0001101001001011; /* 0x1a4b */
int mask = 0b0000111000000000; /* 0x0e00 */
/* &'ed: 0b0000101000000000; 0x0a00 */
int extract = mask & number; /* 0x0a00 */
if (extract == 0b0000101000000000)
/* or if 0b is not available:
if (extract == 0x0a00 ) */
{
/* success */
}
else
{
/* failure */
}
source to share
Masking is done by setting all bits except the one (s) you want to be 0. So let's say you have an 8-bit variable and you want to check if the 5th bit is from 1. Let's say that your variable 00101100
. To mask all other bits, we set all bits except the 5th to 0 using the and operator:
00101100 & 00010000
Now that this is done for every bit except the 5th, the bit from the byte on the right will be 0, so the result of the operation will be 0. For the 5th bit, however, the value from the right bit is 1, so the result will be that the value hte of the 5th bit from the left byte - in this case 0:
Now, to test this value, you have to compare it to something. To do this, just compare the result with the byte on the right:
result = (00101100 & 00010000) == 00000000
To summarize this, you can get any bit from the left byte simply by left shift 00000001 until you get the bit you want. This function does the following:
int getBit(char byte, int bitNum)
{
return (byte & (0x1 << (bitNum - 1)))
}
This works on vars of any size, be it 8, 16, 32, or 64 (or whatever for that matter).
source to share
You need to hide and . Either change the value you are comparing or the value being compared. I find it easier to think by moving the value you are comparing. So if you are trying to extract the 5th and 7th digits (from the left), you shift 9 positions (16-7) to the right , so that the 7th digit is now the rightmost, then apply 0x7 (111 in binary) as masks to get only the rightmost three binary digits
int i = 0x1A4B;
if (((i >> 9) & 0x07) == 0x05) { // 0x05 = 101 in binary
//do what you need to
}
source to share
First, the binary digits are (usually) counted from the right (10th and 12th digits) or you say the 5th and 7th most significant digits.
int mask = 0x0E00; // 0000 1110 0000 0000;
int extract = mask & number;
leads to:
extract = 0000 1010 0000 0000
You can do
if (extract == 0x0A00 /*0000 1010 0000 0000*/){}
or:
if (( extract >> 9 ) == 0x05){}
Both if statements will return true with your sample number.
Usually with a mask, you will find yourself experiencing one digit. You can use a function like this to test it:
bool digit_value( unsigned int number, unsigned int digit)
{
return (1 << digit) & number;
}
int main()
{
unsigned int number = 0x1A4B;
int should_be_three = 0;
should_be_three += digit_value(number, 10);
should_be_three += !digit_value(number, 11);
should_be_three += digit_value(number, 12);
printf("%s", (should_be_three == 3?"it worked":"it didn't work"));
return 0;
}
source to share
It may be easier to check the bits one by one rather than all at once. First, you create a mask for the bit of interest:
int fifthBitMask = 1 << 4;
int fifthBitResult = number & fifthBitMask;
int seventhBitMask = 1 << 6;
int seventhBitResult = number & seventhBitMask;
You can now compare the results with a null OR with a mask. Comparison with zero can be omitted, so you can just use a simple one if:
if (fifthBitResult && seventhBitResult)
{
//your code here
}
Also, you can compare with masks. After the & operation, this will only set the bits that were set in the mask. So you might like this: if (fifthBitResult == 5thBitMask && seventhBitResult == sevenhBitMask) {// Your code here}
So, if the result of the operation is equal to the mask, you can do it with one operation:
int mask = 0x5 << 4; // 0x5 is hex representation of 101b
int result = number & mask;
if (result == mask)
{
// your code here
}
source to share