在c编程中计算带符号的32位整数的二进制数字

时间:2014-05-26 19:12:23

标签: c 32-bit signed twos-complement

我有以下函数来计算无符号32位整数中的二进制位数。

uint32_t L(uint32_t in)
{
   uint32_t rc = 0;

   while (in)
   {
      rc++;
      in >>= 1;
   }

   return(rc);
}

如果有签名的32位整数,有人能告诉我,我应采取哪种方法?实施两个补充是一个选择。如果你有更好的方法,请告诉我。

3 个答案:

答案 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);

http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

答案 2 :(得分:0)

您的负数始终显示为32,因为有符号的负整数的第一个数字是1. UInt4 1000 = 16Int4 1000 = -8,{{ 1}} Int41001 = -7 Int4等...

由于1010 = -6中的第一个数字是有意义的而不仅仅是一些填充,因此您无法忽略它。