我有以下函数来计算无符号32位整数中的二进制位数。
uint32_t L(uint32_t in)
{
uint32_t rc = 0;
while (in)
{
rc++;
in >>= 1;
}
return(rc);
}
如果有签名的32位整数,有人能告诉我,我应采取哪种方法?实施两个补充是一个选择。如果你有更好的方法,请告诉我。
答案 0 :(得分:1)
怎么样:
uint32_t count_bits(int32_t in)
{
uint32_t unsigned_in = (uint32_t) in;
uint32_t rc = 0;
while (unsigned_in)
{
rc++;
unsigned_in >>= 1;
}
return(rc);
}
只需将 signed int 转换为 unsigned ,并执行与之前相同的操作。
BTW:我想你知道 - 除非你的处理器有一个特殊的指令并且你可以访问它 - 计算这些位的最快实现之一是:int count_bits(unsigned x) {
x = x - ((x >> 1) & 0xffffffff);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0f0f0f0f;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 0x0000003f;
}
虽然不是最快......
答案 1 :(得分:0)
只需重复使用您定义的函数:
int32_t bla = /* ... */;
uin32_t count;
count = L(bla);
您可以将bla
投射到uint32_t
(即L((uint32_t) bla);
)以使转换显式,但C不需要它。
如果您使用的是gcc
,它已经提供了快速实现函数来计算位数,您可以使用它们:
int __builtin_popcount (unsigned int x);
int __builtin_popcountl (unsigned long);
int __builtin_popcountll (unsigned long long);
答案 2 :(得分:0)
您的负数始终显示为32,因为有符号的负整数的第一个数字是1. UInt4
1000 = 16
但Int4
1000 = -8
,{{ 1}} Int4
和1001 = -7
Int4
等...
由于1010 = -6
中的第一个数字是有意义的而不仅仅是一些填充,因此您无法忽略它。