zoukankan      html  css  js  c++  java
  • variable-precision SWAR算法介绍

    BITCOUNT命令是统计一个位数组中非0进制位的数量,数学上称作:”Hanmming Weight“

    目前效率最好的为variable-precision SWAR算法,可以常数时间内计算出多个字节的非0数目,算法设计的非常精巧,值得学习。

    int swar(uint32_t i)
    {
        // (A)
        i = ( i & 0x55555555) + ((i >> 1) & 0x55555555);
    
        // (B)
        i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    
        // (C)
        i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
    
        // (D)
        i = (i * 0x01010101) >> 24);
    
        return i;
    }

    原理解释:

    (A) 0x55555555  二进制为:  0101 0101 0101 0101  0101 0101 0101 0101, 奇位为1, 偶数为0

      如果按照i的二进制表示  b31 b30.......  b7 b6 b5 b4 b3 b2 b1 b0    

         i & 0x55555555  则取出全部的奇数位:         0  b30 ...... 0  b6 0 b4 0 b2 0 b0

         (i >> 1) & 0x55555555 则取出偶数位:        0 b31        0  b7  0 b5 0 b3 0 b1 

      两者相加:                                        + ------------------------------------------

                                                                         0  (b30+b31)     .....         0   (b6+b7)   0   (b4+b5)   0   (b2+b3)    0   (b0+b1)

    原理就是按照二进制2位一个分割,计算该两位的1的数目

    (B) 将 (A)步骤按照二进制2位划分的1的数目按照4个bit位进行累加

    (C) 将  (B)步骤中1的数目按照8个bit位进行累加

    (D)  (C)步骤中已经计算出了8bit划分的2进制的数目

           如     byte3  byte2 byte1  byte0

          y  =    y3      y2      y1      y0

           那么 y * 0x01010101 则实现了 将 y0 y1 y2位和y3位置的累加 则y的值为:

                           byte3            byte2        byte1    byte0

        yn  =     y3+y2+y1+y0        x2             x1         x0    将yn >> 24位 则得到了  y3+y2+y1+y0 的效果。

  • 相关阅读:
    c++ 设计模式6 (Decorator 装饰模式)
    c++ 设计模式7 (Bridge 桥模式)
    c++ 设计模式8 (Factory Method 工厂方法)
    c++ 设计模式9 (Abstract Factory 抽象工厂模式)
    C++类设计2(Class with pointer members)
    C++类设计1(Class without pointer members)
    算法总结—链表
    C++对象内存模型1(堆栈模型)
    PHP 页面编码声明方法详解(header或meta)
    php变量与数组相互转换的方法(extract与compact
  • 原文地址:https://www.cnblogs.com/davad/p/5126611.html
Copyright © 2011-2022 走看看