C语言小结--求一个整数中bit位为1的个数

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u014421520/article/details/82708091

最近开发需要将一个数据做奇偶校验,首先就是要计算出这个数据中bit位为1的个数,有以下几种算法可以达到要求:

1 方法1

我直接上代码,然后分析。

uint16_t get_one_in_data_1(uint16_t data)
{
    uint16_t n = 0;
    while (data > 0)
    {
        if (data & 0x01)
            n++;
        data >>= 1;
    }
    return n;
}

我们依次将输入数据的最低位同bit1进行&运算,如果最低位为1,则n++,然后移位比较下一位。这段代码的精妙之处在于,如果一个i数据的高位是0时,立即结束while循环,这样就提高了效率。注意:这个函数是可以传递32位uint32_t整形数据类型的。直接修改形参就可以了。

2 方法2

先上代码,然后分析。

uint16_t get_one_in_data_2(uint16_t data)
{
    uint16_t n;
    for (n = 0; data; n++)
        data &= data - 1;
    return n;
}

这段代码的思想是,二进数据只有0和1构成,当我们对原数据减一操作时,最低为为0的数据减一后都变为了1,然后&操作后可以消除这些位,举例来说:b'1000减一操作后位b'0111 ,然后再做&操作,结果就为0,这样就判断出该数据中只有一个1,同理其他数据也是一样。该算法的好处是不需要while和for两重循环,提高了执行效率。这样做显然要优于算法1。同样,形参也可以是32位整形变量。

3 方法3

先上代码,然后分析。

const unsigned char numbits_lookup_table[256] = {
    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
    3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
    3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
    4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
    3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
    6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
    4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
    6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
    3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
    6, 7, 6, 7, 7, 8
};

uint16_t get_one_in_data_3(uint16_t data)
{
    uint16_t n = 0;
    n = numbits_lookup_table[data & 0x00ff];
    n += numbits_lookup_table[data>>8 & 0x00ff];
    return n;
}

没错就是效率最高的查表法,时间复杂度只有O(1),查表法不需要循环,不需要判断,执行效率最高,但是占用ROM较多,适合存储大一点的场合使用,但是以目前的处理器水平来说,这点存储是可以忽略不记的,所以,推荐大家使用查表法来做。

总结

三种算法都在vs2017环境测试通过。

三种方法各有千秋,如果最求简洁,可以使用方法2,如果最求高效,可以使用方法3。当然了,还有很多算法可以做到,这里就不再一一介绍。有兴趣的读者可以自己尝试其他算法。

猜你喜欢

转载自blog.csdn.net/u014421520/article/details/82708091
今日推荐