Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mask and extract bits in C

I've been looking at posts about mask but still can't get my head around how to extract certain bits from a number in C.

Say if we have a int number 0001 1010 0100 1011 , so it's hex representation is x1a4b right? If I want to know the 5th to 7th number, which is 101 in this case, shall I use int mask= 0x0000 1110 0000 0000, int extract = mask&number?

Also how can I check if it is 101? I guess == won't work here... Many thanks!

like image 456
stillAFanOfTheSimpsons Avatar asked Oct 14 '14 10:10

stillAFanOfTheSimpsons


People also ask

What is masking bits in C?

Bit masking is simply the process of storing data truly as bits, as opposed to storing it as chars/ints/floats. It is incredibly useful for storing certain types of data compactly and efficiently. The idea for bit masking is based on boolean logic.

What is the purpose of mask bits?

Bit masks are used to access specific bits in a byte of data. This is often useful as a method of iteration, for example when sending a byte of data serially out a single pin. In this example the pin needs to change it's state from high to low for each bit in the byte to be transmitted.

What is a bit mask value?

In Bitmasking, the idea is to visualize a number in the form of its binary representation. Some bits are “set” and some are “unset” , “set” means its value is 1 and “unset” means its value is 0. A “Bitmask” is simply a binary number that represents something.


2 Answers

Masking is done by setting all the bits except the one(s) you want to 0. So let's say you have a 8 bit variable and you want to check if the 5th bit from the is a 1. Let's say your variable is 00101100. To mask all the other bits we set all the bits except the 5th one to 0 using the & operator:

00101100 & 00010000

Now what this does is for every bit except the 5th one, 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 a 1, so the result will be whatever the value of hte 5th bit from the left byte is - in this case 0:

Now to check this value you have to compare it with something. To do this, simply compare the result with the byte on the right:

result = (00101100 & 00010000) == 00000000

To generalize this, you can retrieve any bit from the lefthand byte simply by left-shifting 00000001 until you get the bit you want. The following function achieves this:

int getBit(char byte, int bitNum)
{
    return (byte & (0x1 << (bitNum - 1)))
}

This works on vars of any size, whether it's 8, 16, 32 or 64 (or anything else for that matter).

like image 103
PandaConda Avatar answered Sep 18 '22 22:09

PandaConda


Assuming the 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 */
}
like image 26
alk Avatar answered Sep 21 '22 22:09

alk