BIT Counting: C programming problem
John Worley
worley at ardent.UUCP
Wed Jan 11 04:58:19 AEST 1989
> The problem is the most efficient method to simply count the
> number of on bits in a sixteen bit short. ...
>
> int
> BitCount( num )
> short num;
>
> -Jim Becker ...!sun!athsys!jim
First, the parameter num must be declared unsigned. Otherwise, the high
order bit is propagated in the shift; if set, this is an infinite loop. Also,
since parameters as passed as ints, there may be extra high order bits set
when num is negative.
I prefer the following algorithm:
/* Count the number of bits set in num. While num is not
* zero, increment the count and turn off the lowest bit
* set.
*/
int
BitCout(num)
unsigned short num;
{
int cnt;
for (cnt = 0; num != 0; ++cnt)
num &= num - 1;
return (cnt);
}
For N bit parameters, there will be on average N/2 iterrations if the
numbers are randomly distributed; the simple mask and shift will need an
average of N - 1 iterations (proofs on request). You could speed up the
shift and mask scheme by looking at more than one bit each iteration:
int
BitCount(num)
unsigned short num;
{
static int value2bits[] = {
0, 1, 1, 2,
1, 2, 2, 3,
1, 2, 2, 3,
2, 3, 3, 4
};
int cnt;
for (cnt = 0; num != 0; num >>= 4)
cnt += value2bits[num & 0xf];
return (cnt);
}
However, this requires extra data space, an index computation and a
memory load for each iteration, where as the previous approaches could all
run in registers. For certain architectures and applications, however,
it could run faster.
For the fans (like me) of falling through in switch statements:
int
BitCount(num)
unsigned short num;
{
int cnt;
for (cnt = 0; num != 0; num >>= 2)
switch (num & 0x3) {
case 3:
++cnt;
case 2:
case 1:
++cnt;
case 0:
break;
}
return (cnt);
}
Regards,
John Worley
Ardent Computer
uunet!ardent!worley
More information about the Comp.lang.c
mailing list