簡體   English   中英

計算整數的設置位數

[英]count number of set bits in integer

我正在研究關於位計數的不同方法,或給定整數的人口計數方法,在這幾天里,我試圖弄清楚以下算法是如何工作的

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

我認為計算完x的每個值后,我們將得到

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

如果將其乘以-1,我們將得到-4294967294*x ,但是它如何計算位數?請幫助我很好地理解此方法。

我相信你的意思

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

如《 駭客的喜悅 》一書的封面所示,其中的符號表示向左旋轉而不是向左移動 ,這將產生錯誤的結果並降低投票率。

此方法之所以有效,是因為旋轉會導致x的所有二進制數字出現在所有項的每個可能位中,並且由於2的補數。

舉一個簡單的例子。 考慮僅具有4個二進制數字的數字,其中這些數字可以表示為ABCD ,那么求和意味着:

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

我們注意到,每一列都包含A,B,C,D。現在, ABCD實際上表示“2³A +2²B +2¹C +2⁰D”,因此總和為:

  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)

(A + B + C + D)是x的人口數,(2³+2²+2¹+2⁰)= 0b1111是2的補數中的-1,因此總和是人口數的負數。

該參數可以輕松擴展為32位數字。

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

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM