bitParity - 查找整数中的奇数位
Posted
技术标签:
【中文标题】bitParity - 查找整数中的奇数位【英文标题】:bitParity - Finding odd number of bits in an integer 【发布时间】:2012-02-26 08:15:31 【问题描述】:我必须创建一个函数bitParity(int x)
,它接受一个整数并返回1
,如果x
的位形式有奇数个0
,否则返回0
。
例如:bitParity(5) = 0, bitParity(7) = 1
但是,这很困难,因为我只能在这个问题上使用位运算符(! ˜ & ˆ | + << >>
是唯一合法的)。这意味着,没有循环、if-then
或任何类似的东西。可以使用常量。
到目前为止,我所拥有的不起作用,但我认为我应该将整数 16
、8
和 4
的位移位,并将剩余的整数 XOR
移位。
谁能给点建议?谢谢。
【问题讨论】:
您应该始终检查按位示例的第一个位置是graphics.stanford.edu/~seander/bithacks.html#ParityLookupTable 查找表是最好的方法。 256 字节的存储空间是一个很小的代价。如果您使用 32 位整数,只需从表中读取 4 次。 除了@Joe 提到的,你也可以参考catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know。这有一些我觉得很有用的原始技巧。 看看这个***.com/a/21618038/2672154 【参考方案1】:对于 32 位数字:
function bitParity(int x)
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x &= 0xf;
return (0x6996 >> x) & 1;
注意* 0x6996 表示数字 1、2、4、7、8、11、13 和 14 的位向量。所有 4 位值都可以用一个奇数位。在 0x6996 中,如果它在向量中的位置对应于(1、2、4、7、8、11、13 或 14),则设置一个位。
这就是为什么 (0x6996 >> x) & 1 有意义的原因,在移位 x 之后,如果 x 等于位向量中的任何值,则此表达式只会返回 1,这意味着奇数位已设置。
【讨论】:
魔术解释:x ^= x>>16
之后,低16位与原来的奇偶校验相同。再多两行,你就有 4 位具有正确的奇偶校验。在&=
之后,您有一个介于 0 和 15 之间的数字(具有正确的奇偶校验)。 0x6996
用作查找表 - 对于 0 到 15 之间的每个数字,您可以选择其中一个位。
@Joe - 正如 ugoren 解释的那样,0x6996
是一个很小的查找表;) 这只是一种超高效的方法,需要 很多 的理解。 ..但它有效。【参考方案2】:
这可以通过循环正确解决。但这里有一种不用的方法。
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)
编辑:我不需要 &。更好的版本:
x ^= x >> 16
x ^= x >> 8
x ^= x >> 4
x ^= x >> 2
x ^= x >> 1
x &= 1;
【讨论】:
非常感谢!我非常接近,但错过了最后的 x&1。你能告诉我你是如何得出这个结论的吗?谢谢。 我不确定。我正在考虑它,我有一个脑电波。我的第一个想法是对所有位进行异或运算,一次一个。但这将是丑陋的。通过这种方式,我将其想象为将数字反复折叠到自身上。【参考方案3】:这是我在完成学士论文时使用的函数之一 ;)
/** 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]
);
所以 4B 整数的总数为:
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));
和奇偶校验:
return bytes%2;
return bytes&1; // if you preffer
我一直想重用这些代码 :)
编辑:
正如您可能注意到的那样,unsigned char
(8b) 可以分成 2 块,每块 4b 长,这意味着 16 个值易于存储和重用。所以你从整数中取出第一个 8b,将它们分成两部分。确保它们都在间隔<0,15>
中,并且直接获取位数。重复:)
【讨论】:
请看约束。以上是关于bitParity - 查找整数中的奇数位的主要内容,如果未能解决你的问题,请参考以下文章