计算' 1s'的数量在一个字节

时间:2014-09-12 09:23:15

标签: c embedded microcontroller conditional-statements memory-efficient

测试环境: 硬件:微控制器

语言:C

编译器:IAR,HEW,MPLAB,Keil ......

我们有一个测试变量

uint8_t unTestVar;  // uint8_t is type def to unsigned char (8-bit)

如果在程序流程中有一些值在此unTestVar中移动,我们如何有效地计算其中的1的数量。

假设

unTestVar = 0xA0;  // unTestVar is 10100000 in binary

所以这里有两个1。 同样地,

unTestVar = 89;    // unTestVar is 10000110 in binary

这里我们有三个1。

是的,有很多方法可以计算1的数量,但哪种方法是有效的(减少处理和内存使用)。请注意,我的资源环境非常有限。

1 个答案:

答案 0 :(得分:1)

const uint8_t m1 = 0x55;
const uint8_t m2 = 0x33;
const uint8_t m3 = 0x0F;
a = (a & m1) + ((a >> 1) & m1);
a = (a & m2) + ((a >> 2) & m2);
a = (a & m3) + ((a >> 4) & m3);

在此之后包含答案。如果您不想松开a,请使用uint_8类型的临时变量。

<强>解释 添加两位总是适合2位。 (00,01或10)。使用m1,偶数位置的所有位(将0视为偶数并从0开始计数)与奇数位的位相加。 (向下移动1个地方并使用面具)

a = (a & m1) + ((a >> 1) & m1);

       +--+--+--+--+--+--+--+--+
a      |b7|b6|b5|b4|b3|b2|b1|b0|
       +--+--+--+--+--+--+--+--+

       +--+--+--+--+--+--+--+--+
m1     | 0| 1|| 0| 1| 0| 1| 0| 1
       +--+--+--+--+--+--+--+--+

       +--+--+--+--+--+--+--+--+
a & m1 | 0|b6| 0|b4| 0|b2| 0|b0|
       +--+--+--+--+--+--+--+--+

       +--+--+--+--+--+--+--+--+
a>>1   | 0|b7|b6|b5|b4|b3|b2|b1|
       +--+--+--+--+--+--+--+--+

       +--+--+--+--+--+--+--+--+
a>>1&m1| 0|b7| 0|b5| 0|b3| 0|b1|
       +--+--+--+--+--+--+--+--+

Adding (a&m1) and (a >> 1) & m1 and assigning to a
       +--+--+--+--+--+--+--+--+
a      |b7+b6|b5+b4|b3+b2|b1+b0|
       +--+--+--+--+--+--+--+--+

同样继续下一步a = (a & m2) + ((a >> 2) & m2);

           +--+--+--+--+--+--+--+--+
    m2     | 0| 0| 1| 1| 0| 0| 1| 1|
           +--+--+--+--+--+--+--+--+

           +--+--+--+--+--+--+--+--+
  a >> 2   |  0  |b7+b6|b5+b4|b3+b2|
           +--+--+--+--+--+--+--+--+

           +--+--+--+--+--+--+--+--+
    a&m2   |  0  |b5+b4|  0  |b1+b0|
           +--+--+--+--+--+--+--+--+

           +--+--+--+--+--+--+--+--+
 a>>2&m2   |  0  |b7+b6|  0  |b3+b2|
           +--+--+--+--+--+--+--+--+

Adding (a&m2) and (a >> 2) & m2 and assigining to a
           +--+--+--+--+--+--+--+--+
     a     |b7+b6+b5+b4|b3+b2+b1+b0|
           +--+--+--+--+--+--+--+--+

第三步a = (a & m3) + ((a >> 4) & m3);

           +--+--+--+--+--+--+--+--+
    m3     | 0| 0| 0| 0| 1| 1| 1| 1|
           +--+--+--+--+--+--+--+--+

           +--+--+--+--+--+--+--+--+
  a >> 4   |  0  |  0  |b7+b6|b5+b4|
           +--+--+--+--+--+--+--+--+

           +--+--+--+--+--+--+--+--+
    a&m3   |  0  |  0  |b3+b2|b1+b0|
           +--+--+--+--+--+--+--+--+

           +--+--+--+--+--+--+--+--+
 a>>4&m3   |  0  |  0  |b7+b6|b5+b4|
           +--+--+--+--+--+--+--+--+

Adding (a&m2) and (a >> 2) & m2 and assigining to a
           +--+--+--+--+--+--+--+--+
     a     |b7+b6+b5+b4+b3+b2+b1+b0|
           +--+--+--+--+--+--+--+--+

所以最后a包含所有位的总和。 0位在总和中没有贡献,因此它实际上包含设置位的计数。