#include <stdio.h> // 求一字节无符号整数二进制中1的个数 int count_a(unsigned char val); int count_b(unsigned char val); int count_c(unsigned char val); int count_d(unsigned int val); int count_e(unsigned int val); int main() { unsigned char val_byte = 234; printf("%d/n", count_a(val_byte)); printf("%d/n", count_b(val_byte)); printf("%d/n", count_c(val_byte)); unsigned int val_uint = 1243253; printf("%d/n", count_d(val_uint)); printf("%d/n", count_e(val_uint)); return 0; } int count_a(unsigned char val) { int num = 0; while (val) { if (val % 2 != 0) num++; val = val / 2; } return num; } int count_b(unsigned char val) { int num = 0; while (val) { num += val & 0x01; val = val >> 1; } return num; } int count_c(unsigned char val) { int num = 0; while (val) { val &= (val - 1); num++; } return num; } /* 这里用的是二分法,两两一组相加,之后四个四个一组相加, 接着八个八个,最后得到各位之和 */ int count_d(unsigned int val) { val = val - ((val >> 1) & 0x55555555); val = (val & 0x33333333) + ((val >> 2) & 0x33333333); val = (val + (val >> 4)) & 0x0F0F0F0F; val = val + (val >> 8); val = val + (val >> 16); return val & 0x0000003F; } /* 首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。 因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。 这个程序只需要十条左右指令,而且不访存,速度很快。 由此可见,衡量一个算法实际效果不单要看复杂度,还要结合其他情况具体分析。 */ int count_e(unsigned int val) { unsigned n; n = (val >> 1) & 033333333333; val = val - n; n = (n >> 1) & 033333333333; val = val - n; val = (val + (val >> 3)) & 030707070707; val %= 63; return val; }