测试环境: 硬件:微控制器
语言: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的数量,但哪种方法是有效的(减少处理和内存使用)。请注意,我的资源环境非常有限。
答案 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
位在总和中没有贡献,因此它实际上包含设置位的计数。