Reputation: 113
I'm going through "Elements of Programming Interviews" and the very first question is about computing the parity of a number ( whether the number of 1's in the binary representation is even or odd). The final solution provided does this:
short Parity(unsigned long x) {
x ^= x >> 32;
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x &= 0xf;
...
I understand that with that final value of x you can lookup the answer in a lookup table = 0x6996
. But my question is why does the above code work? I've worked a 16 bit example out by hand and it does give the correct parity, I just don't understand it conceptually.
Upvotes: 4
Views: 894
Reputation: 33
For an n bit number x, the answer is always in the rightmost n/(2 to the power z) bits of x after z iterations. Let's take an example where n=8 and x=10110001 (b7, b6, b5, b4, b3, b2, b1, b0).
It's actual/correct answer is even_parity.
After 1 iteration
10110001
00001011
___________
x = 10111010
Rightmost 8/(2 to the power 1) = 4 digits of x = 1010(even parity)
After 2 iterations
10111010
00101110
___________
x = 10010100
Rightmost 8/(2 to the power 2) = 2 digits of x = 00(even parity)
After 3 iterations
10010100
01001010
___________
x = 11011110
Rightmost 8/(2 to the power 3) = 1 digit of x = 0(even parity)
Now we can extract any dth digit of a number b by ANDING it with a number q in which only the dth digit is 1(one) and all other digits are 0(zero).
Here we want to extract the (0th digit)/(rightmost digit) of final value of x.
So let's AND it(i.e, ( final_value_of_x
(i.e, 11011110)
)
after (
2 to the power(
log n to the base 2
)
) iterations
) with 00000001 to get the answer.
11011110
00000001
_________________
00000000
Upvotes: 2
Reputation: 39013
The lookup table is confusing. Let's drop it and keep going:
...
x ^= x >> 2;
x ^= x >> 1;
p = x&1;
To figure it out, let's start with the 1-bit case. In the 1-bit case, p=x, so if x is 1 the parity is odd, and if x is 0 the parity is even. Trivial.
Now the two bit case. You look at b0^b1 (bit 0 XOR bit 1) and that's the parity. If they're equal, the parity is even, otherwise it's odd. Simple, too.
Now let's add more bits. In the four bit example - b3 b2 b1 b0, we calculate x ^ (x>>2)
, which gives us a two bit number: b3^b1 b2^b0 . These are actual two parities - one for the odd bits of the original number, and one for the even bits of the original number. XOR the two parities and we get the original parity.
And now this goes on and on for us many bits as you want.
Upvotes: 5
Reputation: 64904
It works because,
That gives a recursive algorithm by splitting every string down the middle until it's a base case, which you can then group by layer and flip upside down to get the code shown in the question .. sort of, because it ends early and apparently does the last step by lookup.
Upvotes: 3