簡體   English   中英

有人可以解釋一下bitCount代碼如何工作嗎?

[英]Can someone explain how this bitCount code works?

這是我的助教幫助我獲得的代碼,但后來我完全忘記了它是如何工作的,因為我似乎無法獲得正確的答案,面試成績將於明天開始。 如果有人可以幫忙,請做。 謝謝

* bitCount - returns count of number of 1's in word
*   Examples: bitCount(5) = 2, bitCount(7) = 3
*   Legal ops: ! ~ & ^ | + << >>
*   Max ops: 40
*   Rating: 4
*/
int bitCount(int x) {
    int m4 = 0x1 | (0x1<<8) | (0x1<<16) | (0x1<<24);
    int m1 = 0xFF; 
    int s4 = (x&m4) + ((x>>1)&m4) + ((x>>2)&m4) + ((x>>3)&m4) + ((x>>4)&m4) + ((x>>5)&m4) + ((x>>6)&m4) + ((x>>7)&m4);
    int s1 = (s4&m1) + ((s4>>8)&m1) + ((s4>>16)&m1) + ((s4>>24)&m1);
    return s1;
}

將其轉換為位表示形式時,通常更容易看到與位相關的操作中發生的情況:

假設int為32位,則以下是m4和m1的位表示形式:

0000 0001 0000 0001 0000 0001 0000 0001 //m4, masking across the 4 bytes
0000 0000 0000 0000 0000 0000 1111 1111 //m1, masking only 1 byte, the Least Significant Byte (LSB)

我想m代表mask ,而4&1分別代表4個字節和1個字節

然后棘手的部分是s4。 您可能需要逐步檢查它以了解它的含義。

首先,請注意右移和m4的掩蔽:

pqrs tuvw pqrs tuvw pqrs tuvw pqrs tuvw // x
0000 0001 0000 0001 0000 0001 0000 0001 //m4
---------------------------------------- &
0000 000w 0000 000w 0000 000w 0000 000w //x&m4

pqrs tuvw pqrs tuvw pqrs tuvw pqrs tuvw // x
---------------------------------------- >> 1
0pqr stuv wpqr stuv wpqr stuv wpqr stuv // x >> 1
0000 0001 0000 0001 0000 0001 0000 0001 //m4
---------------------------------------- &
0000 000v 0000 000v 0000 000v 0000 000v //(x>>1)&m4
.
.
pqrs tuvw pqrs tuvw pqrs tuvw pqrs tuvw // x
---------------------------------------- >> 7
0000 000p qrst uvwp qrst uvwp qrst uvwp // x >> 7
0000 0001 0000 0001 0000 0001 0000 0001 //m4
---------------------------------------- &
0000 000p 0000 000p 0000 000p 0000 000p //(x>>7)&m4

其次,請注意從以上結果中獲得的8個元素的加法:

0000 000w 0000 000w 0000 000w 0000 000w //x&m4
0000 000v 0000 000v 0000 000v 0000 000v //(x>>1)&m4
.
.
0000 000p 0000 000p 0000 000p 0000 000p //(x>>7)&m4
---------------------------------------- +
//Resulting in s4

因此,由於p到w各自只能為0或1,並且您擁有八個這樣的元素,因此,每8位段中您具有:

p+q+r+s+t+u+v+w // each element is either 0 or 1

從那里可以清楚地看到,以上添加的8個元素的結果范圍為0到8。

也就是說,每8位段將獲得0000 0000(十進制表示為0-如果全為0)到0000 1000(十進制表示為8-如果全為1)。

因此,您將擁有以下格式的s4:

0000 abcd 0000 efgh 0000 ijkl 0000 mnop // s4

其中abcdefghijklmnop是每個字節加p到w的結果。

現在,請注意,您獲得了x分布在4個字節中的位數的總和

總和,我想這就是變量中的s代表的總和)

0000 abcd //byte 1, left most, MSB
0000 efgh //byte 2, second from left
0000 ijkl //byte 3, second from right
0000 mnop //byte 4, rightmost, LSB

因此,您需要將結果合並到s4中的這四個字節中,以找到一個字節中的總和

(我想這就是s1的意思: sum in a byte

您通過以下方式獲得s1:

  1. 用0、8、16、24移位s4
  2. 用0xFF屏蔽每個
  3. 並合並(添加)結果。

因此,發生以下操作(在位級別):

0000 abcd 0000 efgh 0000 ijkl 0000 mnop // s4
0000 0000 0000 0000 0000 0000 1111 1111 //m1 
--------------------------------------- &
0000 0000 0000 0000 0000 0000 0000 mnop

0000 0000 0000 abcd 0000 efgh 0000 ijkl // s4 >> 8
0000 0000 0000 0000 0000 0000 1111 1111 //m1 
--------------------------------------- &
0000 0000 0000 0000 0000 0000 0000 ijkl

.
.

0000 0000 0000 0000 0000 0000 0000 abcd // s4 >> 24
0000 0000 0000 0000 0000 0000 1111 1111 //m1 
--------------------------------------- &
0000 0000 0000 0000 0000 0000 0000 abcd

可以看出,您僅添加了以下四個元素:

0000 0000 0000 0000 0000 0000 0000 mnop //0 to 8
0000 0000 0000 0000 0000 0000 0000 ijkl //0 to 8
0000 0000 0000 0000 0000 0000 0000 efgh //0 to 8
0000 0000 0000 0000 0000 0000 0000 abcd //0 to 8
--------------------------------------- +
//Final result, s1

您可以簡單地將四個數字相加,每個數字的取值范圍為0到8。因此,它必須得出0到32的值(0表示全為0,32表示全為8),即位數。在變量x中為1。 因此該函數名為bitCount

函數就是這樣工作的。


最后的注意:知道這一點,您甚至可以用0x0F(而不是0xFF)更改m1,結果仍然相同。

在此聲明之后:

    int s4 = (x&m4) + ((x>>1)&m4) + ((x>>2)&m4) + ((x>>3)&m4) + ((x>>4)&m4) + ((x>>5)&m4) + ((x>>6)&m4) + ((x>>7)&m4);

由於S4中有4個字節,因此它的1個字節在x的相應字節中將具有1的數目。因此,顯然,s4的每個字節在x的相應字節中均具有1的數目。

然后在語句中:int s1 =(s4&m1)+((s4 >> 8)&m1)+((s4 >> 16)&m1)+((s4 >> 24)&m1);

現在s4的1個字節在x的相應字節中將具有1的數目,然后將s4右移至8位將在x的字節2中給出2的數目,以此類推,這將是4個字節。 然后將所有數相加得到x的1的數目。

暫無
暫無

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

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