32位数的1的数字
我正在寻找一种方法,在32位数字中使用1的数字而不使用其间的循环。 任何人都可以帮助我,并为我提供代码或算法。 提前致谢。
请参见Integer.bitCount(int)
。 如果你想看看它是如何工作的,你可以参考源代码; 许多Integer
类的小巧程序来自Hacker’s Delight。
请参阅规范参考: Bit Twiddling Hacks
简短,优化的答案(在C中):
int pop(unsigned x) { x = x - ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0F0F0F0F; x = x + (x >> 8); x = x + (x >> 16); return x & 0x0000003F; }
要了解为什么这种魔法有效,请参阅美国 法典第10章Henry S. Warren,Jr。的“寻求加速人口计数 ” 。
将32位数字拆分为4位8位数(参见位移运算符,转换等)
然后使用具有256个条目的查找,将8位数转换为设置的位数。 添加四个结果,presto!
另外,看看Mitch Wheat说的话 – 小小的摆弄可以很有趣;)
您可以递归地定义它:
int bitcount(int x) { return (x==0) ? 0 : (x & 1 + bitcount(x/2)); }
上面的代码未经过测试,可能仅适用于x> = 0。 希望你能得到这个想法……
我个人最喜欢的,直接来自Bit Twiddling Hacks :
v = v - ((v >> 1) & 0x55555555); v = (v & 0x33333333) + ((v >> 2) & 0x33333333); c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
以下是Integer.bitCount的JDK 1.5实现
public static int bitCount(int i) { // HD, Figure 5-2 i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; }