BOP 計算32位整型數中的1的個數

2021-06-03 13:58:32 字數 1755 閱讀 9488

一、hakmem演算法分析

1、整型數 i 的數值,實際上就是各位乘以權重——也就是乙個以2為底的多項式:

i = a0*2^0+a1*2^1+a2*2^2+...

因此,要求1的位數,實際上只要將各位消權:

a0+a1+a2+...  即係數和就是'1'的個數。

2、定理:對任何自然數n的n次冪,用n-1取模得數為1。

證明:若 n^(k-1) % (n-1) = 1 成立

則 n^k % (n-1) = ((n-1)*n^(k-1) + n^(k-1)) % (n-1) = 0 + n^(k-1) % (n-1)  = 1 也成立

又有 n^(1-1) % (n-1) = 1

故對任意非負整數n, n^n %(n-1)=1

3、因此,對乙個係數為的以n為底的多項式p(n) = a0*n^n0+a1*n^n1+a2*n^n2+...

p(n)%(n-1) = (sum()) % (n-1) ;

如果能保證sum() < (n-1),則 p(n)%(n-1) = (sum())  

也就是說,此時只要用n-1對多項式取模,就可以完成消權,得到係數和。

於是,問題轉化為,將以2為底的多項式轉化為以n為底的多項式,其中n要足夠大,使得n-1 > sum()恆成立。

32位整型數中ai=0或1,sum()<=32。n-1 > 32 ,n需要大於33。

因此取n=2^6=64>33作為新多項式的底。

4、將32位二進位制數的每6位作為乙個單位,看作以64為底的多項式:

i = t0*64^0 + t1*64^1 + t2*64^2 + t3*64^3 + ...

各項的係數ti就是每6位2進製數的個數。

這樣,只要通過運算,將各個單位中的6位數變為這6位中含有的'1'的個數,再用63取模,就可以得到所求的總的'1'的個數。

5、取其中任意一項的6位數ti進行考慮,最簡單的方法顯然是對每次對1位進行mask然後相加,即

(ti>>5)&(000001) + (ti&>>4)(000001) + (ti>>3)&(000001) + (ti>>2)&(000001) + (ti>>1)&(000001) + ti&(000001)

二、**

1、由上面分析可以得到**:

int  bitcount(unsigned  int  n)   

返回的就是1的個數。簡單吧

2、化簡一

上面是計算每六位中1的個數,得到上面原理分析的ti

但是,6位數中最多只有6個'1',也就是000110,只需要3位有效位,所以有些浪費

如果先得到每三位中1的個數,然後加一下也得到每六位1的個數,**如下:

int  bitcount(unsigned  int  n)   

這樣又減少了幾步!!

3、化簡二

如何計算三位中1的個數,如三位abc,1的個數無非是計算 a+b+c

乙個3位2進製數值是4a+2b+c

如果右移一位,變成2a+b;再右移一位,變成a

而(4a+2b+c) - (2a+b) - a = a+b+c  得到的就是我們想要的數

所以改**如下:

int  bitcount(unsigned  int  n)   

這樣又少了兩步,這才是最最簡單,複雜度最低的求1的個數的方法!!

**:

數32位 unsigned int中1的個數

參考文章 最簡單的方法 int bitcount0 unsigned int n return c 消除統計法 int bitcount2 unsigned int n return c 8bit查表法 unsigned int table 256 int bitcount2 unsigned in...

RK平台計算GPIO對應的整型數

gpio是比較常用的資源,比如說控制led燈亮滅,控制lcd上電,控制模組的復位電路,做外設的中斷腳等等,這些都有對gpio的操作和使用,所以說,gpio開發是驅動開發中必不可少的操作,而且也是最基礎的東西。我們在驅動開發過程中,有時候我們不能確定自己使用和申請的gpio是否對了,我們可以把它對應的...

計算機32位與64位的區別

叨叨32位和64位的區別,其實不嚴謹。32位 64位 指的可能是cpu,可能是作業系統,可能是安裝的軟體 多數情況說的計算機32位,64位指的就是cpu的區別,作業系統也屬於特殊的軟體吧 32 64位cpu的區別 1.控制匯流排能力不同 32位cpu只能控制32根匯流排 64位cpu可以控制64根匯...