数字中设置的位数
Number of bits set in a number
以下神奇公式给出了数字中设置的位数(汉明权重)。
/*Code to Calculate count of set bits in a number*/
int c;
int v = 7;
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
printf(" Number of Bits is %d",c);
/*-----------------------------------*/
从:http://graphics.stanford.edu/~seander/bithacks.html
谁能解释一下这背后的理由?
它确实是非常聪明的代码,显然比简单的朴素循环更难理解。
对于第一行,我们只取一个四位数量,并将其称为abcd
。代码基本上是这样做的:
abcd - ((abcd >> 1) & 0101) = abcd - (0abc & 0101) = abcd - 0a0c
因此,在每组两位中,它减去高位的值。这是什么让我们净赚的?
11 - 1 -> 10 (two bits set)
10 - 1 -> 01 (one bit set)
01 - 0 -> 01 (one bit set)
00 - 0 -> 00 (zero bits set)
因此,第一行将每组连续的两位设置为原始值中包含的位数 - 它计算以两个为一组设置的位。调用生成的四位数量ABCD
。
下一行:
(ABCD & 0011) + ((ABCD>>2) & 0011) = 00CD + (AB & 0011) = 00CD + 00AB
因此,它采用两个位的组并将对相加。现在,每个四位组都包含在输入的相应四位中设置的位数。
在下一行中,v + (v >> 4) & 0xF0F0F0F
(解析为 (v + (v >> 4)) & 0xf0f0f0f
)执行相同的操作,将四位组对添加在一起,以便每个八位组(字节)包含相应输入字节的位集计数。我们现在有一个像 0x0e0f0g0h
这样的数字.
请注意,将任何位置的字节乘以 0x01010101
都会将该字节复制到最高有效字节(并在较低的字节中保留一些副本)。例如,0x00000g00 * 0x01010101 = 0x0g0g0g00
.因此,通过乘以 0x0e0f0g0h
,我们将e+f+g+h
留在最上面的字节中;末尾的>>24
提取该字节并留下答案。
python 中的一个行解决方案,用于计算给定二进制数中的 1 个
[i for i in str(bin(n)) if i=="1"].count("1")
相关文章:
- 使用设置精度时如何阻止数字向上舍入?
- 您可以使用 setfill() 来设置 fill 2 位数字吗?
- 如何正确取消设置64位数字中的位?
- 找到非常大的数字的最右边的未设置位
- 根据参数设置十进制数字
- 如何设置数字格式以显示C 中的所有小数位数
- 如何将精度设置为C 的100位数字
- 设置::使用数字中的引号进行向量初始化
- MinGW中的数字格式设置更改
- 找到使用 2 个设置位形成的第 n 个数字
- 将数字设置在小数点后的浮子中
- 当区域设置需要"3,14"时,如何使用scanf解析像"3.14"这样的数字
- 将数字动态数组设置为数组或容器 c++
- 为什么 for 循环没有达到循环的第二个条件中设置的数字
- 十进制数字的区域设置感知编辑控件子类化(格式[sign][xxx..][decimal separator][yy.])
- 在小数点之前设置数字的精度
- 如何将精度设置为一个数字
- 将数字从字符串流转换为具有设置精度的字符串
- 如何在C++中设置生成随机数的特定数字
- C++ 标准::设置<string>字母数字自定义比较器