简体   繁体   English

有人可以解释一下bitCount代码如何工作吗?

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

This is code that my TA help me get, but then I completely forgot how it worked exactly since I can't seem to get the right answer, and the interview grading is tomorrow. 这是我的助教帮助我获得的代码,但后来我完全忘记了它是如何工作的,因为我似乎无法获得正确的答案,面试成绩将于明天开始。 If anybody can help please do. 如果有人可以帮忙,请做。 Thanks 谢谢

* 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;
}

It is often easier to see what happen in the bit-related operation when you convert it to its bit representation: 将其转换为位表示形式时,通常更容易看到与位相关的操作中发生的情况:

Assuming the int is 32-bit, then the following are the m4 & m1 in their bit-representation: 假设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)

I suppose m stands for mask , while 4 & 1 refer to 4 bytes and 1 byte respectively 我想m代表mask ,而4&1分别代表4个字节和1个字节

And then the tricky part is the s4. 然后棘手的部分是s4。 You might need to examine it step by step to get the idea of what it is. 您可能需要逐步检查它以了解它的含义。

Firstly, note the right-bitwise-shift and the masking with m4: 首先,请注意右移和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

And secondly, note the addition of the 8 elements obtained from above results: 其次,请注意从以上结果中获得的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

Thus, since p to w each can only be 0 or 1 and you have eight of such element, consequently, per 8-bit segment you have: 因此,由于p到w各自只能为0或1,并且您拥有八个这样的元素,因此,每8位段中您具有:

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

From there, it can be seen clearly that the result for the addition 8 elements above would range from 0 to 8. 从那里可以清楚地看到,以上添加的8个元素的结果范围为0到8。

That is, you will get 0000 0000 (0 in decimal representation - if all is 0) to 0000 1000 (8 in decimal representation - if all is 1) per 8-bit segment. 也就是说,每8位段将获得0000 0000(十进制表示为0-如果全为0)到0000 1000(十进制表示为8-如果全为1)。

Consequently, you will have the s4 in the following format: 因此,您将拥有以下格式的s4:

0000 abcd 0000 efgh 0000 ijkl 0000 mnop // s4

Where abcd , efgh , ijkl , and mnop are the result of additions p to w per byte. 其中abcdefghijklmnop是每个字节加p到w的结果。

Now, notice that you get the sum of the number of bits in x spread across the 4 bytes. 现在,请注意,您获得了x分布在4个字节中的位数的总和

( sum I suppose this is what s in the variables stands for - sum) 总和,我想这就是变量中的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

Thus, you need to combine the result in those four bytes in s4 to find the sum in one byte 因此,您需要将结果合并到s4中的这四个字节中,以找到一个字节中的总和

(and I suppose, this is what s1 stands for: sum in one byte ) (我想这就是s1的意思: sum in a byte

You get s1 by: 您通过以下方式获得s1:

  1. Shifting s4 with 0, 8, 16, 24 用0、8、16、24移位s4
  2. Mask each of them with 0xFF 用0xFF屏蔽每个
  3. And combine (add) the results. 并合并(添加)结果。

Hence, the following operations (in the bit level) occur: 因此,发生以下操作(在位级别):

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

It can be seen that you simply have the following additions of four elements: 可以看出,您仅添加了以下四个元素:

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

You have simple addition of four numbers, each having value of 0 to 8. Thus, it must result in a value of 0 to 32 (0 is when all is 0, 32 is when all is 8), which is the number of bit 1 in the variable x. 您可以简单地将四个数字相加,每个数字的取值范围为0到8。因此,它必须得出0到32的值(0表示全为0,32表示全为8),即位数。在变量x中为1。 And thus the function is named bitCount . 因此该函数名为bitCount

That is how the function works. 函数就是这样工作的。


Final note: knowing this, you could even change m1 with 0x0F (instead of 0xFF) and the result would still be the same. 最后的注意:知道这一点,您甚至可以用0x0F(而不是0xFF)更改m1,结果仍然相同。

After this statement : 在此声明之后:

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

As there are 4 bytes in S4, then 1 byte of it will have the number of 1's in corresponding byte of x So, clearly each byte of s4 hold the number of 1's in the corresponding byte of x. 由于S4中有4个字节,因此它的1个字节在x的相应字节中将具有1的数目。因此,显然,s4的每个字节在x的相应字节中均具有1的数目。

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

Now 1 byte of s4 will have the number of 1's in corresponding byte of x, then right shift of s4 to 8 bits will give the number of 2's in byte 2 of x, so on for 4 bytes. 现在s4的1个字节在x的相应字节中将具有1的数目,然后将s4右移至8位将在x的字节2中给出2的数目,以此类推,这将是4个字节。 Then adding all will give the number of 1's in x. 然后将所有数相加得到x的1的数目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM