How to create mask with least significat bits set to 1 in C

39,104

Solution 1

The usual way is to take a 1, and shift it left n bits. That will give you something like: 00100000. Then subtract one from that, which will clear the bit that's set, and set all the less significant bits, so in this case we'd get: 00011111.

A mask is normally used with bitwise operations, especially and. You'd use the mask above to get the 5 least significant bits by themselves, isolated from anything else that might be present. This is especially common when dealing with hardware that will often have a single hardware register containing bits representing a number of entirely separate, unrelated quantities and/or flags.

Solution 2

A mask is a common term for an integer value that is bit-wise ANDed, ORed, XORed, etc with another integer value.

For example, if you want to extract the 8 least significant digits of an int variable, you do variable & 0xFF. 0xFF is a mask.

Likewise if you want to set bits 0 and 8, you do variable | 0x101, where 0x101 is a mask.

Or if you want to invert the same bits, you do variable ^ 0x101, where 0x101 is a mask.

To generate a mask for your case you should exploit the simple mathematical fact that if you add 1 to your mask (the mask having all its least significant bits set to 1 and the rest to 0), you get a value that is a power of 2.

So, if you generate the closest power of 2, then you can subtract 1 from it to get the mask.

Positive powers of 2 are easily generated with the left shift << operator in C.

Hence, 1 << n yields 2n. In binary it's 10...0 with n 0s.

(1 << n) - 1 will produce a mask with n lowest bits set to 1.

Now, you need to watch out for overflows in left shifts. In C (and in C++) you can't legally shift a variable left by as many bit positions as the variable has, so if ints are 32-bit, 1<<32 results in undefined behavior. Signed integer overflows should also be avoided, so you should use unsigned values, e.g. 1u << 31.

Solution 3

First, for those who only want the code to create the mask:

uint64_t bits = 6;
uint64_t mask = ((uint64_t)1 << bits) - 1;
# Results in 0b111111 (or 0x03F)

For those who want to know what a mask is:

A mask is usually a name for value that we use to manipulate other values using bitwise operations such as AND, OR, XOR, etc.

Short masks are usually represented in binary, where we can explicitly see all the bits that are set to 1.

Longer masks are usually represented in hexadecimal, that is really easy to read once you get a hold of it.

You can read more about bitwise operations in C here go you get a better grasp of the material.

Share:
39,104
sebi
Author by

sebi

Updated on April 30, 2020

Comments

  • sebi
    sebi about 4 years

    Can someone please explain this function to me?

    A mask with the least significant n bits set to 1.

    Ex:

    n = 6 --> 0x2F, n = 17 --> 0x1FFFF // I don't get these at all, especially how n = 6 --> 0x2F

    Also, what is a mask?