3

我对一个名为OpenBCI的新 IoT 项目感兴趣,它基本上是一个开源 EEG,用于读取和处理脑电波和其他生物数据。在他们的文档中,他们声称无线传输的数据(通过 RFDuino)发送 24 位数据。要将 24 位值转换为 32 位有符号整数,他们建议使用以下 Java 友好的处理代码:

int interpret24bitAsInt32(byte[] byteArray) {
    int newInt = (
        ((0xFF & byteArray[0]) << 16) |
        ((0xFF & byteArray[1]) << 8) |
        (0xFF & byteArray[2])
    );

    if ((newInt & 0x00800000) > 0) {
        newInt |= 0xFF000000;
    } else {
        newInt &= 0x00FFFFFF;
    }

    return newInt;
}

我想我正试图准确地了解这里发生了什么。让我们看一下第一段代码:

int newInt = (
    ((0xFF & byteArray[0]) << 16) |
    ((0xFF & byteArray[1]) << 8) |
    (0xFF & byteArray[2])
);
  • 为什么假设输入中有 3 个字节是安全的?
  • 价值的意义0xFF何在?
  • 左移 ( <<) 的目的是什么?

第二段也有点神秘:

if ((newInt & 0x00800000) > 0) {
    newInt |= 0xFF000000;
} else {
    newInt &= 0x00FFFFFF;
}
  • 为什么newInt & 0x00800000?有什么意义0x00800000
  • 为什么if-else基于上述操作的正负结果?
  • 0xFF000000和的意义是0x00FFFFFF什么?

我想我想更好地理解这个功能有很多挥手和魔法!

4

1 回答 1

8

为什么假设输入中有 3 个字节是安全的?

24 位 / 8 位 = 3 字节

0xFF 值的意义是什么?

这有点面具。0b11111111在二进制。在这种情况下,它被用作将字节值转换为 int 的快速方法。

左移(<<)的目的是什么?

一旦在上一条指令中检索到 int 值,它就会向左移动 16 位以获取 int 的第三个字节的位置(从右侧开始计数)。这是由于字节数组以大端格式存储字节,其中 MSB 位于首位。下一个字节只需移动 8 位即可占据第二个字节的位置,最后一个字节根本不需要移动,因为它已经在第一个字节位置。

为什么 newInt & 0x00800000?0x00800000有什么意义?

那么0x80是另一个位掩码来获取某个字节的 MSB。0x00800000对应于第三个字节的 MSB(即byteArray[0]在前一个过程中左移 16 位的字节)。这也对应于整个 24 位值的 MSB。

为什么 if-else 基于上述操作的正负结果?

确定 24 位值的 MSB 是 1 还是 0 将分别以二进制补码表示法告诉我们它是负数还是正数。

0xFF000000和0x00FFFFFF的意义是什么?

如果数字在 24 位表示中为负数,我们还希望它在二进制补码中作为 32 位值是负数,这就是为什么我们必须0b11111111使用 OR 运算符用 (0xFF) 填充第 4 个和最后一个字节。
如果它已经是正数,那么第四个字节可以是 0x00,接下来的 3 个字节与原始的 24 位值相同 - 通过用 屏蔽来完成0x00FFFFFF

于 2016-04-14T20:00:29.773 回答