0

i am studing different methods about bit counting ,or population count methods fopr given integer, during this days,i was trying to figure out how following algorithms works

pop(x)=-sum(x<<i)   where i=0:31

i think that after calculate each value of x,we will get

x+2*x+4*x+8*x+16*x+..............+2^31*x  =4294967294*x

if we multiply it by -1,we get -4294967294*x,but how it counts number of bits?please help me to understand this method well.thanks

  • This method doesn't work. If you think it does work, write it in code and test it. – interjay Mar 22 '12 at 13:45
  • Visit this site: http://graphics.stanford.edu/~seander/bithacks.html It explains every bit operation you need. – linello Mar 22 '12 at 13:47
  • Are you sure you have that right? If I understand your notation, then putting `x=8` (for instance) gives a sum of binary 11111111 11111111 11111111 11111000, so -sum is binary 00...001000 = decimal 8. But when I counted the bits by hand, I got the answer 1. – TonyK Mar 22 '12 at 13:48
  • It actually seems to return `pop(x) == x` for every x. – interjay Mar 22 '12 at 13:50
  • Is that what it does? It doesn't look like it to me. – mcmcc Mar 22 '12 at 13:52
  • Ah, so it's a clever way of computing `x` from `x`. – TonyK Mar 22 '12 at 13:52
  • ok let's suppose that it is not correct,and i did not know it,it is taken from book,where author said ,that he is going to leave it as a task for read,why are somebody is downvoting it?it means that, should i have to fear of posting such question which i did not understand well and want to know it? –  Mar 22 '12 at 13:58
  • 2
    It means that you should have tried out a couple of values of `x` before you posted (just like everybody here did). – TonyK Mar 22 '12 at 14:04

2 Answers2

6

I believe you mean

$$\mathrm{pop}(x) = -\sum_{i=0}^{31} (x \overset{\mathrm{rot}}{\ll} i)$$

as seen in the cover of the book Hacker's Delight, where the symbol means left-rotation not left-shift which will produce the wrong results and downvotes.

This method works because the rotation will cause all binary digits of x to appear in every possible bits in all terms, and because of 2's complement.

Take a simpler example. Consider numbers with only 4 binary digits, where the digits can be represented as ABCD, then the summation means:

  ABCD  // x <<rot 0
+ BCDA  // x <<rot 1
+ CDAB  // x <<rot 2
+ DABC  // x <<rot 3

We note that every column has all of A, B, C, D. Now, ABCD actually means "2³ A + 2² B + 2¹ C + 2⁰ D", so the summation is just:

  2³ A        + 2² B        + 2¹ C        + 2⁰ D
+ 2³ B        + 2² C        + 2¹ D        + 2⁰ A
+ 2³ C        + 2² D        + 2¹ A        + 2⁰ B
+ 2³ D        + 2² A        + 2¹ B        + 2⁰ C
——————————————————————————————————————————————————————
= 2³(A+B+C+D) + 2²(B+C+D+A) + 2¹(C+D+A+B) + 2⁰(D+A+B+C)
= (2³ + 2² + 2¹ + 2⁰) × (A + B + C + D)

The (A + B + C + D) is the population count of x and (2³ + 2² + 2¹ + 2⁰) = 0b1111 is -1 in 2's complement, so the summation is the negative of the population count.

The argument can be easily extended to 32-bit numbers.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
0
#include <stdio.h>
#include <conio.h>

unsigned int f (unsigned int a , unsigned int b);

unsigned int f (unsigned int a , unsigned int b)
{
   return a ?   f ( (a&b) << 1, a ^b) : b;
}

int bitcount(int n) {
    int tot = 0;

    int i;
    for (i = 1; i <= n; i = i<<1)
        if (n & i)
            ++tot;

    return tot;
}

int bitcount_sparse_ones(int n) {
    int tot = 0;

    while (n) {
        ++tot;
        n &= n - 1;
    }

    return tot;
}

int main()
{

int a = 12;
int b = 18;

int c = f(a,b);
printf("Sum = %d\n", c);

int  CountA = bitcount(a);
int  CountB = bitcount(b);

int CntA = bitcount_sparse_ones(a);
int CntB = bitcount_sparse_ones(b);

printf("CountA = %d and CountB = %d\n", CountA, CountB);
printf("CntA = %d and CntB = %d\n", CntA, CntB);
getch();

return 0;

}
kapilddit
  • 1,729
  • 4
  • 26
  • 51