我试着在C中计算一个整数值中设置的位数。但对于某些值,它显示正确的位集计数,而对于某些值,它则不是。
PFB程序代码
int main()
{
int a = 512, i = 0, j = 1, count = 0, k = 0;
for (i = 0; i < 31; i++)
{
if (k = a & j)
{
count++;
j = j << 1;
}
}
printf("the total bit set count is %d", count);
}
设置位值计数512的输出显示为零,如果使用的值为511,则计数显示为9。
请帮我修改一下程序。
8条答案
按热度按时间dluptydi1#
斯坦福大学有一页介绍了实现常见位旋转操作的不同方法。他们列出了5种不同的算法来计算位集,所有这些都有C示例。
https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
最简单的实现:
xe55xuns2#
如果使用的是gcc/clang编译器,可以使用内置函数**_builtin_popcount**
当我不寻找跨平台,我会使用这个功能,因为它的高度优化。
kiayqfof3#
一般来说,你会在一个无符号整数中计算位数。原因是,您通常会检查寄存器或掩码中的位设置。有符号整数是用two’s-complement表示的,我想不出你为什么要在有符号整数中计算集合位(如果你确实想要这样做,你会感兴趣的)。
请注意,在C中,如果数字为负,则向右或向左移动有符号整数是实现定义的行为。来自C标准第6.5.7节:
. E1 << E2的结果是E1左移E2比特位置;.如果E1具有带符号类型和非负值,并且E1 << E2在结果类型中是可表示的,那么这就是结果值;否则,行为未定义。
E1 >> E2的结果是E1右移E2位位置。.如果E1具有带符号类型和负值,则结果值是实现定义的.
如果你想在一个任意大小的unsigned整数中计算1的个数,你可以使用this example:
在这个例子中,
value
可以是unsigned char,unsigned long,任何unsigned integer类型。注意:不要移动有符号值或浮点数/双精度数。
oxosxuxt4#
您可以使用除法
/
和模%
运算符来检查整数中设置的位。rggaifut5#
您正在检查
a&j
的值,如果a&j
为0,则不做任何其他操作,而是重试。你的
j
-bitshift需要在if-then之外。gopyfrb36#
你犯了几个错误:
请注意,与其使用硬编码值32表示
int
中的位数,不如这样做:这样,如果
int
的大小是例如,代码仍然可以工作。16位或64位。c90pui9n7#
虽然严格来说这不是C语言,但你可以使用内联汇编来调用
POPCNT
x86操作:根据this benchmark,像在idok's answer中那样调用
__builtin_popcount
与上面的代码一样快,它们都比任何其他C实现快得多。您也可以查看链接的repo以获取其他解决方案。xv8emn3q8#