Question

I would like to calculate an inverse mask for an unsigned char.meaning if the original mask 0xc0 the the inverse mask should be 0x3f.that is to say all the bits should be flipped or inverted.I have tried the below but doesn't seem to be working.

int flipBit(int x, unsigned char position)
{
  int mask = 1 << position;
  return x ^ mask;
}

int main(int argc , char* argv[])
{
        uint8_t mask = 0x03;
        uint8_t inverse_mask = 0;
        uint8_t temp = 0;
        int loop = 0;

        for (loop = 0; loop < 8 ; loop ++)
        {
                temp = flipBit(mask,loop);
                inverse_mask |= temp;
        }
        printf("mask 0x%x inv mask 0x%x \n",mask,inverse_mask);
        return 0;
}

The results I get are mask 0x3 inv mask 0xff

I cannot seem to find the bug in my code.

Was it helpful?

Solution

Use the ~ (bitwise-not) operator.

inverse_mask = ~mask;

OTHER TIPS

Why can't you just do this:

uint8_t mask = 0x03;
uint8_t inverse_mask = ~mask;

There are many ways you can do it.

Let's say you have this binary value:

x = 01110110

As a human, we can identify it's "inverse" as:

y = 10001001

Now let us see it's properties:

  • Every bit of y is the not of the corresponding bit in x
    • This operation is done in C like this: y = ~x;
    • Alternatively, we know that one bit xor 1 gives not of that bit, so y = x^0xFF;
  • Sum of any bit plus its not is 1, without a carry. Therefore y+x == 0xFF
    • Therefore, y = 0xFF-x;

As to why your program doesn't work, let's follow the loop:

loop: 0
  mask:         0000 0011
  temp:         0000 0010
  inverse_mask: 0000 0010
loop: 1
  mask          0000 0011
  temp          0000 0001
  inverse_mask: 0000 0011
inverse_mask eventually: 0xFF

You could see the problem in the very first loop: you got a one in the second place of inverse_mask that you shouldn't have.

If you wanted temp to hold only the bit that was flipped, you should have written in flibBit, instead of:

return x ^ mask;

this line:

return (x & mask) ^ mask;

So that you first isolate the bit, then flip it.

I explained so you learn the error in your program, you should still use one of the methods I mentioned first.

This is very simple to do using XOR.

uint8_t mask = 0x03;
uint8_t inverse_mask = mask ^ 0xFF;

Your flipBit function should return at most one bit only for your code to work:

0x03 ^ 0x01 = 0x02
0x03 ^ 0x02 = 0x01
0x03 ^ 0x04 = 0x07
0x03 ^ 0x08 = 0x0b
0x03 ^ 0x10 = 0x13
0x03 ^ 0x20 = 0x23
0x03 ^ 0x40 = 0x43
0x03 ^ 0x80 = 0x83
0x2 ^ 0x1 ^ 0x7 ^ 0xb ^ 0x13 ^ 0x23 ^ 0x43 ^ 0x83 = 0xff

int flipBit(uint8_t x, unsigned char position)
{
  int mask = 1 << position;
  return (x & mask) ^ mask;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top