什么是Hanmming weight?
Hanmming weight简单来说就是求一个串中1的个数。可以求8位中的,也可以求16位中的,也可以求32位,64位中的1的个数。
For the most typical case, a string of
bits
, this is the number of 1's in the string, or the
digit sum
of the
binary representation
of a given number and the
ℓ₁ norm
of a bit vector. 在大多数典型的例子中,一个字符串中的位数,就是字符串中1的个数。参考https://en.wikipedia.org/wiki/Hamming_weight
我的理解
在这里说下我的理解,这个算法利用了分治的思想,首先自己与0x5(0101)相与,这样可以求出奇数位1个数,然后向右移位一位,再与0x5(0101)相与求出偶数位1的个数,然后再相加可以求出原数中两位中1的个数并且存放在各自的两位中,一直这样进行下去,直到结果存放在低位中这样得到的一个数就是最终所需要的1的个数,然后久可以返回了。
//types and constants used in the functions below
//uint64_t is an unsigned 64-bit integer variable type (defined in C99 version of C language)
const uint64_t m1 = 0x5555555555555555; //binary: 0101...
const uint64_t m2 = 0x3333333333333333; //binary: 00110011..
const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ...
const uint64_t m8 = 0x00ff00ff00ff00ff; //binary: 8 zeros, 8 ones ...
const uint64_t m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
const uint64_t m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
const uint64_t hff = 0xffffffffffffffff; //binary: all ones
const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
//This is a naive implementation, shown for comparison,
//and to help in understanding the better functions.
//This algorithm uses 24 arithmetic operations (shift, add, and).
int popcount64a(uint64_t x)
{
x = (x & m1 ) + ((x >> 1) & m1 ); //put count of each 2 bits into those 2 bits
x = (x & m2 ) + ((x >> 2) & m2 ); //put count of each 4 bits into those 4 bits
x = (x & m4 ) + ((x >> 4) & m4 ); //put count of each 8 bits into those 8 bits
x = (x & m8 ) + ((x >> 8) & m8 ); //put count of each 16 bits into those 16 bits
x = (x & m16) + ((x >> 16) & m16); //put count of each 32 bits into those 32 bits
x = (x & m32) + ((x >> 32) & m32); //put count of each 64 bits into those 64 bits
return x;
}