算法一:
const int one_in_char[256]=
{
0, 1, 1, 2, 1, 2,2,3
......
,8
}
//此为 0-255 每个数中 1 的个数。
//这个雕虫小技在密码,crc...等地方使用很广泛。
int func2(int v)
{
int n=v;
unsigned char *ptr=(unsigned char *)&n;
return one_in_char[ptr[0]]+one_in_char[ptr[1]]+one_in_char[ptr[2]]+one_in_char[ptr[3]];
}
算法二:
unsigned int func(unsigned int x)
{
x = (x & 0x55555555UL) + ((x >> 1) & 0x55555555UL); // 0-2 in 2 bits
x = (x & 0x33333333UL) + ((x >> 2) & 0x33333333UL); // 0-4 in 4 bits
#if 1
// Version 1
x = (x & 0x0f0f0f0fUL) + ((x >> 4) & 0x0f0f0f0fUL); // 0-8 in 8 bits
x = (x & 0x00ff00ffUL) + ((x >> 8) & 0x00ff00ffUL); // 0-16 in 16 bits
x = (x & 0x0000ffffUL) + ((x >> 16) & 0x0000ffffUL); // 0-31 in 32 bits
return x;
#else
// Version 2
x = (x + (x >> 4)) & 0x0f0f0f0fUL; // 0-8 in 4 bits
x += x >> 8; // 0-16 in 8 bits
x += x >> 16; // 0-32 in 8 bits
return x & 0xff;
#endif
}
对比测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
int count=0x7FFFFFFF;
unsigned int func(unsigned int x)
{
x = (x & 0x55555555UL) + ((x >> 1) & 0x55555555UL); // 0-2 in 2 bits
x = (x & 0x33333333UL) + ((x >> 2) & 0x33333333UL); // 0-4 in 4 bits
#if 1
// Version 1
x = (x & 0x0f0f0f0fUL) + ((x >> 4) & 0x0f0f0f0fUL); // 0-8 in 8 bits
x = (x & 0x00ff00ffUL) + ((x >> 8) & 0x00ff00ffUL); // 0-16 in 16 bits
x = (x & 0x0000ffffUL) + ((x >> 16) & 0x0000ffffUL); // 0-31 in 32 bits
return x;
#else
// Version 2
x = (x + (x >> 4)) & 0x0f0f0f0fUL; // 0-8 in 4 bits
x += x >> 8; // 0-16 in 8 bits
x += x >> 16; // 0-32 in 8 bits
return x & 0xff;
#endif
}
int one_in_char[256];
int func2(int *v)
{
unsigned char *ptr=(unsigned char *)v;
return one_in_char[ptr[0]]+one_in_char[ptr[1]]+one_in_char[ptr[2]]+one_in_char[ptr[3]];
}
void test_1()
{
int t1, t2;
int i, v;
char v2=0;
t1 = time(NULL);
for (i=0; i<count; i++)
{
v = func(i);
v2+=v; /* 若不加这个,v 没使用,循环被优化掉了 */
}
t2 = time(NULL);
printf("time of func: %d v2=%d\n", t2-t1, v2);
}
void test_2()
{
int t1, t2;
int i, v;
char v2=0;
for (i=0; i<256; i++)
one_in_char[i]=i%8; /* 这 256 为硬编码, 为简便起见,随便设,不影响计算时间 */
t1 = time(NULL);
for (i=0; i<count; i++)
{
v = func2(&i);
v2+=v; /* 若不加这个,v 没使用,循环被优化掉了 */
}
t2 = time(NULL);
printf("time of func2: %d v2=%d\n", t2-t1, v2);
}
int main(int argc, char **argv)
{
test_1();
test_2();
return 0;
}