Exercise 2-7

Write a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.

At first, you may think that we will need to separate the bits we need to compute, invert them, and then combine them with the original string. However, there is a simpler method. Notice that when bits are XORed with ones, they get inverted (e.g. 1010binary ^ 1111binary = 0101binary.) Now, this exercise becomes trivial. We create the necessary bitmask by starting with ~0U, shifting it p bits left, inverting it, and shifting it p + 1 - n bits left. Then, we simply use the XOR operator on x and the bitmask.

    /* invert:  return x with n bits starting from p inverted */
    unsigned invert(unsigned x, int p, int n)
    {
        return x ^ ((~(~0U << n)) << (p + 1 - n));
    }