-3

I have following function which counts the number of binary digits in an unsigned 32-bit integer.

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

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

   return(rc);
}

Could anyone tell me please in case of signed 32-bit integer, which approach i should take ? implementing two's complement is an option. if you have any better approach, please let me know.

Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28
rzmuc
  • 243
  • 1
  • 5
  • 10

3 Answers3

1

What about:

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);
}

Just convert the signed int into an unsigned one and do the same thing as before.

BTW: I guess you know that - unless your processor has a special instruction for it and you have access to it - one of the fastest implementation of counting the bits is:

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;
}

It's not the fastest though...

Codo
  • 75,595
  • 17
  • 168
  • 206
  • i tried your first approach, it always shows 32 in case of negative value. is it right ? – rzmuc May 26 '14 at 21:26
0

Just reuse the function you defined as is:

int32_t bla = /* ... */;
uin32_t count;

count = L(bla);

You can cast bla to uint32_t (i.e., L((uint32_t) bla);) to make the conversion explicit, but it's not required by C.

If you are using gcc, it already provides fast implementations of functions to count bits and you can use them:

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

ouah
  • 142,963
  • 15
  • 272
  • 331
  • I think the OP means "any digit", not just "1-digits". But then again, I don't think the OP understands the question at all; he's been cranking out "how to do X for signed integers" en masse all day. – Kerrek SB May 26 '14 at 23:32
0

Your negative number always shows 32 because the first digit of a signed negative integer is 1. A UInt4 of 1000 = 16 but an Int4 of 1000 = -8, an Int4 of 1001 = -7, and Int4 of 1010 = -6 etc...

Since the first digit in an Int32 is meaningful rather just a bit of padding, you cannot really ignore it.

Frank van Wijk
  • 3,234
  • 20
  • 41