问题
I have to create a function bitParity(int x)
that takes an integer and returns 1
if there is an odd number of 0
's in the bit form of x
, and 0
otherwise.
Ex: bitParity(5) = 0, bitParity(7) = 1
However, this is difficult as I can only use bit operators on this problem (! ˜ & ˆ | + << >>
are the only legal ones). That means, no loops, if-then
, or anything of the sort. Constants can be used.
So far, what I have doesn't work, but I figured that I should shift the bits of the integer 16
, 8
, and 4
times and XOR
the remaining integers.
Can anyone offer some advice? Thanks.
回答1:
This is properly solved with a loop. But here is a way to do it without.
x = (x & 0x0000FFFF) ^ (x >> 16)
x = (x & 0x000000FF) ^ (x >> 8)
x = (x & 0x0000000F) ^ (x >> 4)
x = (x & 0x00000003) ^ (x >> 2)
x = (x & 0x00000001) ^ (x >> 1)
Edit: I don't need the &. A better version:
x ^= x >> 16
x ^= x >> 8
x ^= x >> 4
x ^= x >> 2
x ^= x >> 1
x &= 1;
回答2:
For 32bit numbers:
function bitParity(int x) {
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x &= 0xf;
return (0x6996 >> x) & 1;
}
Note* 0x6996 represents a bit vector of the numbers 1, 2, 4, 7, 8, 11, 13, and 14. All of the 4-bit values that can be represented by an odd number of bits. In 0x6996, a bit is set if its position in the vector corresponds with (1, 2, 4, 7, 8, 11, 13, or 14).
This is why (0x6996 >> x) & 1 makes sense, after the shift by x, this expression will only result in a returned 1 if x is equal to any of the values in the bit vector, meaning an odd number of bits were set.
回答3:
Here's one of my functions that I used during my work on bachelor thesis ;)
/** Calculates number of bits in unsigned char
* @brief Bit count
* @param input to be checked
* @return int 0-8
*/
int bitCount( unsigned char input)
{
static unsigned char count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
return (int)(
count[ input & 0x0f] +
count[ (input >> 4) & 0x0f]
);
}
So total count for 4B integer would be:
int bytes = bitCount( (unsigned char)((number >> 0)&255))
+ bitCount( (unsigned char)((number >> 8)&255))
+ bitCount( (unsigned char)((number >> 16)&255))
+ bitCount( (unsigned char)((number >> 24)&255));
And parity:
return bytes%2;
return bytes&1; // if you preffer
I always wanted to reuse those codes :)
EDIT:
As you may noticed unsigned char
(8b) can be split into 2 pieces each 4b long, that means 16 values which are easy to store and reuse. So you take first 8b from integer, split them into two pieces. Make sure them are both in interval <0,15>
, and just directly get bit count. Repeat :)
来源:https://stackoverflow.com/questions/9133279/bitparity-finding-odd-number-of-bits-in-an-integer