Today, we saw an issue about the "algorithm for judging the number of 1 in 32-bit integer binary" in Cu. Because I am about to leave work soon, and I have no time to study it again. I had to copy the address of the post in the Forum first. Learning ing ....
Http://dev.bibts.com/32-1-t936968.htm
Http://www.chinaunix.net/jh/23/795048.html
The following is a detailed description of the problem:
Http://www.everything2.com/index.pl? Node = counting % 201% 20 bits
Http://www.everything2.com/index.pl? Node = counting % 201% 20 bits % 20 Spoiler
Http://www.everything2.com/index.pl? Node_id = 1181258
When I first saw this problem, I started to write code:
Unsigned int findoneinnumber_00 (unsigned int X)
{
Unsigned int I, j = 1;
Unsigned int COUNT = 0;
For (I = 0; I <32; I ++)
{
If (X & J )! = 0) Count ++;
J = j <2;
}
Return count;
}
Obviously, my code is very bad. Each time a number is passed in, I always need to perform 32 scans. At this point, we can say that my code is a typical spam code. Do other people have concise code. Some items are found in the above three English URLs.
Unsigned int findoneinnumber_01 (unsigned int X)
{
Unsigned int N;
For (n = 0; X; x> = 1)
If (X & 1) n ++;
Return N;
}
The first method provided by the original author in the English document. When you see such code, you can only say that you are too stupid and the code is too silly to write. Isn't it the number of 1 in a number? Why do I have to scan all the bits? This is a question worth thinking about. The Code provided by the original author is already very good. However, next he gives the second solution, which is more concise and elegant.
Unsigned int findoneinnumber_02 (unsigned int X)
{
Unsigned int N;
For (n = 0; X; n ++)
X & = X-1;
Return N;
}
The second method provided by the original author is obviously better than the first method. In both programs, after the loop body is executed, N indicates one number. The value of X is 0. Both of them achieve the same purpose, and the number of cycles is the same. However, the difference between the two lies in that the second method does not need to execute conditions to determine the jump. When the data volume is large, the gap between the two is quite large.
The author of the original article provides the third method to solve this problem:
Unsigned findoneinnumber_03 (unsigned int X)
{
Const unsigned mask1 = 0x55555555;
Const unsigned mask2 = 0x33333333;
Const unsigned mask4 = 0x0f0f0f;
Const unsigned mask8 = 0x00ff00ff;
Const unsigned mask16 = 0x0000ffff;
X = (X & mask1) + (x> 1 & mask1 );
X = (X & mask2) + (x> 2 & mask2 );
X = (X & mask4) + (x> 4 & mask4 );
X = (X & mask8) + (x> 8 & mask8 );
X = (X & mask16) + (x> 16 & mask16 );
Return X;
}
A friend of the original author provides another method: [query table method]. However, it is a waste of primary storage. This method is also a very good method, but it is a problem when it is developed under the microcontroller. Like our company developing games on single chip microcomputer, all Rom space that can be provided to pictures, sounds, and programs is only 8 Mb. it is unwise to adopt this method.
Unsigned numbits_lookup_table [1, 256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 3, 3, 4, 2, 3, 3, 4, 4, 5, 2, 3,
3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 5, 6, 1, 2, 2, 3, 3, 3, 4, 2, 3, 3,
4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 5, 6, 2, 3, 3, 4,
3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
6, 7, 6, 7, 7, 8
};
Unsigned findoneinnumber_04 (unsigned int X)
{
Unsigned N;
N = numbits_lookup_table [X & 0xff];
N + = numbits_lookup_table [x> 8 & 0xff];
N + = numbits_lookup_table [x> 16 & 0xff];
N + = numbits_lookup_table [x> 24 & 0xff];
Return N;
}