问题
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.
回答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...
回答2:
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
回答3:
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.
来源:https://stackoverflow.com/questions/23876378/counting-the-binary-digits-of-a-signed-32-bit-integer-in-c-programming