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));
}