variable-precision SWAR算法“计算汉明重量”

统计一个位数组中非0位的数量,数学上称作:”Hanmming Weight“,汉明重量

SWAR算法计算汉明重量C实现是这样的

// 计算32位二进制的汉明重量
int32_t swar(int32_t i)
{   
    i = (i & 0x55555555) + ((i >> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
    i = (i * (0x01010101) >> 24);
    return i
}

先看上面几个特殊的十六进制数

0x55555555  的二进制为 0101  0101  0101  0101  0101  0101  0101  0101, 奇位为1, 偶数为0

0x33333333  的二进制为 0011  0011  0011  0011  0011  0011  0011  0011

0x0F0F0F0F 的二级制为 0000  1111  0000  1111  0000  1111  0000  1111

0x01010101  的二进制为 0000  0001  0000  0001  0000  0001  0000  0001, 每个字节最后一位是1

1、第一步,(i & 0x55555555) + ((i >> 1) & 0x55555555)

i &0x55555555            得到  j,j  的偶数为全为0,奇数位与 i 的奇数位相对应。

(i >> 1) & 0x55555555   得到 q,q 的偶数位全为0,奇数位与 i 的偶数位相对应。

(i & 0x55555555) + ((i >> 1) & 0x55555555) 即 j + q 得到 z ,z 的第 1 位 和第 2 位的二级制表示(00或01或10)就是 i 的第 1、2 位中值为 1 的数量。这样 z 中每两位一组的二进制表示记录了 i 中对应的两位上的非 0 的个数。

2、第二步,i = (i & 0x33333333) + ((i >> 2) & 0x33333333)

该步中的 i 即上一步中得到的 z ,如果该步骤中得到的结果是 y ,那么 y 中每四位一组的二进制表示记录了 i(最开始的那个数) 中对应的四位上的非 0 的个数。

3、第三步,同上,结果是分成四组,每组8个二进制位来表示。

4、第四步,i = (i * (0x01010101) >> 24)

第三步计算完后,其实已经分成了四组,每组八个二进制位,只要求出每组上二进制表示的值,相加的结果就是汉明重量。

假如 i = 0010 0101 0110 0000 1010 0001 0001 0110来看下是怎么乘的


红框右边的值为有效值,由于 i 的类型是 32 位的 int 型,所以红框内已经是最高位,将其向右移动 24 位,就得到了上面的说的汉明重量(不会超过32)

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值