当前位置 博文首页 > dadalaohua的博客:【位操作笔记】计算奇偶性 异或和右移查表法

    dadalaohua的博客:【位操作笔记】计算奇偶性 异或和右移查表法

    作者:[db:作者] 时间:2021-07-27 14:48

    计算奇偶性(Compute parity) 异或和右移查表法

    计算奇偶性(Compute parity)指的是,计算一个数所包含1的个数是奇数还是偶数,例如一个8位数0x5b = 0b?0101 1011?,其中1的个数为5,是奇数;一个8位数0xa3 = 0b??1010 0011?,其中1的个数为4,是偶数。该算法可以用于奇偶校验位的计算与验证。

    算法说明

    先通过移位和位移,将32位数值压缩成4位数值,再使用这个值作为一个索引来进行右移,类似于一个小型的16位奇偶性表格,来查找奇偶性。一共只需要9步运算就可以完成。

    如果设置了奇数位数,返回true,否则返回false。

    实现代码

    bool computing_parity(unsigned int val)
    {
        val ^= val >> 16;
        val ^= val >> 8;
        val ^= val >> 4;
        val &= 0xf;
        return (0x6996 >> val) & 1;
    }
    

    算法计算过程

    1. 第一步和第二步v ^= v >> 16

      将32位数值压缩成16位数值。因为异或操作和奇偶性的特点,这个操作只会减少置位的bit数,但不影响奇偶性。接下来就只关心低16位的数值。

    2. 第三步和第四步v ^= v >> 8

      将16位数值压缩成8位数值。因为异或操作和奇偶性的特点,这个操作只会减少置位的bit数,但不影响奇偶性。接下来就只关心低8位的数值。

    3. 第五步和第六步v ^= v >> 4

      将8位数值压缩成4位数值。接下来就只关心低4位的数值。

    4. 第七步v &= 0xf

      剔除无用的bit位的数据,只剩下低4位的数值。

    5. 第八步0x6996 >> val

      0x6996 转换成二进制就是 0110 1001 1001 0110,这个相当于是一个16位奇偶性表格,通过右移上一步计算出的数值,就能得到数值的奇偶性。

    6. 第九步& 1

      得到奇偶性。

    例如一个数为0x355C4E25,二进制为0b?00110101010111000100111000100101?,共15bit

    1. v ^= v >> 16

    0

    1. v ^= v >> 8
      1

    2. v ^= v >> 4
      2

    3. v &= 0xf

    3

    1. 0x6996 >> val
      4

    2. & 1
      5

    最后得到结果,为奇数。

    完成奇偶性计算。

    完整过程
    11

    拓展

    计算8位的奇偶性 。使用该方法运算,只用5次运算就能完成计算。

    bool computing_parity(unsigned int val)
    {
        val ^= val >> 4;
        val &= 0xf;
        return (0x6996 >> val) & 1;
    }
    

    [参考资料]

    Bit Twiddling Hacks By Sean Eron Anderson

    [Hacker’s Delight] 作者: Henry S. Warren Jr.


    本文链接:https://blog.csdn.net/u012028275/article/details/112644553

    cs