理解按位运算 - 移位和AND

时间:2017-07-25 10:50:49

标签: c++ bit-manipulation xbee

uint8_t payload[] = { 0, 0 };
pin5 = analogRead(A0);
payload[0] = pin5 >> 8 & 0xff;
payload[1] = pin5 & 0xff;

这是由andrewrapp在GitHub上发布的XBee库中的代码。我想知道按位操作是如何工作的。 所以假设引脚5的模拟值为256,因为我使用的是粒子光子板,它的格式为12位格式为000100000000.有效载荷[0]得到最后8位即00000000,或者它在移位后得到的值即ie ,00000001?那么有效载荷[1]中的值是什么?

我想在数组的前四位使用位掩码后跟数据位添加一个4位代码。我可以吗?有效负载[1],为此有0X1到有效负载[1]?

2 个答案:

答案 0 :(得分:0)

示例中的代码将pin5的两个字节的内容反转为payload数组:最重要的字节放在payload[0]中,最低有效字节是放入payload[1]

例如,如果pin50x0A63,则payload将包含0x630x0A

如果pin5具有12位值,则可以使用其四个最高有效位来存储您自己的四位值。要确保高位被清零,请使用0x0F掩码而不是0xFF

payload[0] = pin5 >> 8 & 0x0f;
//                         ^

现在,您可以使用|运算符将数据移动到高四位:

payload[0] |= myFourBits << 4;

答案 1 :(得分:0)

所以你想了解所陈述的操作是做什么的。让我们看看是否可以通过检查pin5变量并将其细分为两部分来澄清这一点:

pin5              000100000000
                  MMMMLLLLLLLL

M = 4个最高有效位,L = 8个最低有效位

payload[0]会在pin5上执行某些操作的结果:

pin5              000100000000
>> 8              000000000001  Shifts all bits 8 positions to the right
                  00000000MMMM  and fills the left part with zeroes

所以你现在有了原先的4位右对齐,在其上执行了一个额外的操作:

                  000000000001
& 0xFF            000011111111  Anding with FF
                  000000000001

将12位变量右移8个位置会留下4个重要位置;前8位始终为0. 0xFF为二进制11111111,即表示8个设置位。所以这里做的是And 4个最低有效位和8个最低有效位,以确保4个最高有效位被擦除。

                  00000000xxxx  Potentially set bits (you have 0001)
                  000011111111  & 0xFF
                  00000000xxxx  Result
                      0000xxxx  Storing in 8-bits variable
payload[0] =          00000001  in your case

在这种情况下,And操作没有用,完全浪费时间,因为And任何带0xFF的变量都不会改变其中任何变量的8个最低位因为无论如何都没有设置4个最重要的位,所以在这个操作中没有任何意义。

(从技术上讲,因为源是一个12位变量(可能是16位变量,只有12个重要(相关)二进制数字),0x0F对于{{1}来说已经足够了你能明白为什么吗?但即使这只是一个浪费的CPU周期。)

And也会在payload[1]上执行操作的结果:

pin5

在这种情况下,Anding pin5 MMMMLLLLLLLL potentially set bits & 0xFF 000011111111 mask to keep LLLLLLLL only 0000LLLLLLLL result (you have 00000000) xxxxxxxx Storing in 8-bits variable payload[1] = 00000000 in your case 非常有意义,因为它会丢弃11111111,在您的情况下为MMMM

所以,总而言之,你的价值

0001

被拆分,pin5 000100000000 MMMMLLLLLLLL 包含payload[0]MMMM =十进制1),0001包含payload[1]LLLLLLLL =十进制0)。

如果输入是

00000000

相反,您会在pin5 101110010001 MMMMLLLLLLLL 中找到:payload[0](十进制8 + 2 + 1 = 11),1011payload[1](十进制128 + 16 + 1 = 145)。

您可以将此结果解释为十进制11 * 256 + 145 = 2961,这与将原始101110010001从二进制转换为十进制时获得的结果相同,例如在程序员模式下使用10010001calc.exe ),如果您使用的是Windows。

同样,原始数据被解释为1 * 256 + 0 = 256,如预期的那样。