Search code examples
c++maskmasking

C++: Mask and decoding bits


I just came across a function I dont understand, and I was wondering if you could explain it to me.

unsigned long long x(unsigned long long value, int begin, int end)
{
    unsigned long long mask = (1 << (end - begin)) - 1;
    return (value >> begin) & mask;
}

Thanks
uksz


Solution

  • The above function serves as a mask to extract a range of bits from a number. It can be broken down into four steps.

    First step:

    mask = 1UL << (end - begin)
    

    The << logically shifts 1 to the left by end - begin bits. Since the binary of 1 is 000001, a shift by 3 would correspond to 001000.

    Second step:

    mask = mask - 1
    

    We have established from the previous step that mask at that point would be a sequence of zeroes, followed a one, followed by end - begin number of zeroes. Subtracting 1 from such a number will result in the end - begin least significant bits being 1, with everything else as 0. Subtracting 1 from our previous example yields 000111.

    Third step:

    value >> begin
    

    This will logically shift the target number (the one from which we need to extract bits) to the right by begin bits. Since we want the bits in the range begin to end, we can leave remove the bits before begin.

    Fourth step:

    (value >> begin) & mask
    

    Taking the characterwise AND with the mask will result in the first begin - end bits of the shifted number being extracted. This is because the 0 & x = 0 and 1 & x = x.

    As pointed out in the other answer by Bathsheba, care should be taken to write 1UL to ensure that the number being shifted is an unsigned int. Else shifting an int by more bits in that int is undefined behavior. 1UL is an unsigned long long int with the value 1.