題目:統計乙個無符號數中的二進位制表示中1的個數。
此演算法名為平行計算法。基本思想如下:
先兩兩(兩個二進位制位)分組統計每組出現的1的個數,而每組1的個數只可能是0個(00),1個(01)或2個(10),由(相加所得的)兩位的二進位制完全可以表示每組(兩個二進位制數)中1的個數;接著四四(4個二進位制位)的分組,每組內有兩個分別用兩位二進位制數表示的數字,而這些兩位二進位制數字又是上一步得來的表示1的個數的,因此在每組內把每兩位二進位制數當作乙個整體的數字來相加,就可以看出四四分組的每四個二進位制裡面有多少個1;以此類推......
下面這張圖很直觀(**於網路)
但是不足以說明我們求解的邏輯過程:例a=1001011101111101(16-bits)
1.兩兩分組,求每組的1的個數
1 0 0 1 0 1 1 0=01 00 00 0100 01 01 00
+ 0 1 1 1 1 1 1 1=00 01 01 01 01 01 01 01
1 1 1 21 2 2 1=01 01 01 10 01 10 10 01
注意:上下兩個二進位制數才是一組,這樣才能實現組內相加, 相加的結果用兩位二進位制來表示。
那麼怎樣用語言來實現呢?
肯定是兩個二進位制數相加來表示的,下面那個只留了8-bits的偶數字,只需把其與0101010101010101相與即可,即1001011101111101&0101010101010101(0x5555)=0001010101010101(01111111),另乙個是只留了奇數字,1001011101111101&1010101010101010(0xaaaa)=1000001000101000,得到的這個位模式不能與上面的那個偶數字直接相加(那不等於原來的數了麼),因為它是向右偏移了一位的(實質上對於原數而言,應該是第1位與第0位相加,第3位與第2位相加...第15位與第14位相加),很顯然,把我們得到的結果右移1位變為0100000100010100即可。
綜上,兩兩分組組內相加的最終表示就是(a&0x5555)+((a&0xaaaa)>>1);
2.四四分組,組內相加,求1的個數(原數變為0101 0110 0110 1001)
01 10 1001=0001 0010 0010 0001
+ 01 01 01 10=0001 0001 0001 0010
10 11 1111=0010 0011 0011 0011
怎樣由0101 0110 0110 1001變為0001 0010 00100001(只保留每組的低兩位),原數與0x3333相與即可,
怎樣由0101 0110 0110 1001變為0001 0001 00010010(只保留每組的高兩位),原數與0xcccc相與是不夠的,同樣存在1中的問題,把相與的結果右移兩位即可.
3.......
其實,問題的核心在於如何把每組的高位和低位剝離,實現組內相加,總結起來就一句話,用的著的位用1相與保留,不用的與0相與置0,組內的空位(在高位)用0補齊(16位),最後,不要忘了移位!
參考資料:
二進位制 二進位制中1的個數
題目 請實現乙個函式,輸入乙個整數,輸出該數二進位制表示中 1 的個數。例如,把 9 表示成二進位制是 1001,有 2 位是 1。因此,如果輸入 9,則該函式輸出 2。示例 1 輸入 00000000000000000000000000001011 輸出 3 解釋 輸入的二進位制串 0000000...
統計二進位制中1的個數(彙編)
data segment str db the result is data ends code segment assume cs code,ds data start mov ax,data mov ds,ax mov dx,offset str mov ah,09h 輸出字串的功能,但是使用前...
二進位制中1的個數 二進位制中0的個數
1 題目 實現乙個函式,輸入乙個整數,輸出該數二進位制表示中1的個數,例如把9表示成二進位制是1001,有2位是1。因此如果輸入9,該函式輸出2。2 解法 解法 一 可能會引起死迴圈的解法 基本思路 先判斷整數二進位制表示中最右邊一位是不是1。接著把輸入的整數右移一位,此時原理處於從右邊數起的第二位...