第10章 寻求快速的种群计数
种群计数(Population Count)或横列和(Sideways Sums)是计算机中基本且出奇简单的算法,用于统计单位计算机字长包含的1位的数量。
基本方法:
实例1:
pop = 0;
while(x){
pop = pop + ( x & 1);
x = x >> 1;
}
实例2:
pop = 0;
while(x){
pop = pop + 1;
x = x & (x-1); //将x的最低的bit值为1的位清零。
}
分治方法:
思路是分治法思路,要计数32 bit的1的个数,分别先计数出左右2个16 bit内的1的个数。依次类推,最后变成先计数16组2 bit内的1的个数。算法执行了Log2( 32 ) = 5 步。
详细原理说明,参照:http://www.matrix67.com/blog/archives/264 内的 “计算二进制中的1的个数“部分。
实例1:
x = ( x & 0x55555555 ) + ( ( x >> 1) & 0x55555555 );
x = ( x & 0x33333333) + ( ( x >> 2) & 0x33333333);
x = ( x & 0x0F0F0F0F) + ( ( x >> 4) & 0x0F0F0F0F);
x = ( x & 0x00FF00FF) + ( ( x >> 8) & 0x00FF00FF);
x = ( x & 0x0000FFFF) + ( ( x >> 16) & 0x00FF00FF);
实例2:
int pop( unsigned x ){
x = x – ((x >> 1) & 0x55555555);
x = ( x & 0x33333333) + ( ( x >> 2) & 0x33333333);
x = (x + (x >> 4) )& 0x0F0F0F0F;
x = x + (x >> 8) ;
x = x + (x >> 16);
return x & 0x0000003F;
}
应用:
种群计数指令可以用于计算字中后缀0的数目,使用如下的关系式:
ntz( x ) = pop( ~x & (x - 1 )) = 32 – pop( x | -x );
函数ntz( x )的应用非常广泛。如用于中断优先顺序的判断。
计算机界传言,种群计数对美国NSA而言非常重要。很有可能是关于加密工作或海量材料的搜索