按位 OR 运算符对 2 的补码字节有什么特殊作用吗?

问题描述

所以我需要深入研究 I2C 上传感器读数的数字表示——对于 I2C 加速度计的读数,有一个步骤我无法理解(粗体部分):

为了读取它们,我们从第一个寄存器开始,使用 requestionFrom() 函数要求读取 6 个寄存器。然后使用 read() 函数,我们从每个寄存器读取数据,由于输出是二进制补码,我们将它们适当组合以获得正确的值。

// === Read acceleromter data === //
Wire.beginTransmission(ADXL345);
Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(ADXL345,6,true); // Read 6 registers total,each axis value is stored in 2 registers
X_out = ( Wire.read()| Wire.read() << 8); // X-axis value <--------------
X_out = X_out/256; //For a range of +-2g,we need to divide the raw values by 256,according to the datasheet
Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
Y_out = Y_out/256;
Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
Z_out = Z_out/256;

https://howtomechatronics.com/tutorials/arduino/how-to-track-orientation-with-arduino-and-adxl345-accelerometer/

这里(在 Arduino 的 C++ 风格中)我们将 X_out 定义为浮点数,我们正在读取 X 轴的两个字节,其中 Wire.read()Wire.read() 位移了 8 倍到左侧(<-------------- 行)。但是按位或操作如何(或者更确切地说为什么)合并两个字节的信息?我无法通过谷歌搜索找到任何明确的答案。这是我不知道的标准吗?

解决方法

按位或只是意味着输出输入的每一位的inclusive OR。与2的补码无关

所以如果我们有两个字节 X 和 Y,位模式分别为 abcdefghABCDEFGH,那么 X | Y << 8 的结果是这样的

Y             00000000ABCDEFGH
Y << 8        ABCDEFGH00000000
X             00000000abcdefgh
──────────────────────────────
X | Y << 8    ABCDEFGHabcdefgh

它有效,因为任何与 0 的 OR 都等于它自己。只要看看 truth table,你就会明白。所以 A OR 0 = AB OR 0 = B0 OR a = a 等等

在这种情况下,+ 和 XOR 也有效,因为 0 XOR x = x0 + x = x。所以X + (Y << 8) == X ^ (Y << 8) == X | (Y << 8)