【问题标题】:24- to 32-bit conversion in JavaJava 中的 24 位到 32 位转换
【发布时间】:2016-04-14 19:13:08
【问题描述】:

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

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 值有什么意义?
  • 左移位 (&lt;&lt;) 的目的是什么?

第二段也有点神秘:

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

我想我想更好地理解这个功能!

【问题讨论】:

  • 最后一部分是符号扩展的晦涩方式,else 分支是无操作的。更明显的是newInt = (newInt &lt;&lt; 8) &gt;&gt; 8

标签: java processing bitwise-operators bit-shift signed-integer


【解决方案1】:

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

24 位 / 8 位 = 3 个字节

0xFF 值的意义是什么?

这是一个位掩码。 0b11111111 二进制。在这种情况下,它被用作将字节值转换为 int 的快速方法。

左移(

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

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

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

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

确定 24 位值的 MSB 是 1 还是 0 将分别以 two's complement 表示法告诉我们它是负数还是正数。

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

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

【讨论】:

  • 很棒,很棒的答案@James Buck (+1) - 谢谢!只是好奇,如果我在 Java 中实现它,并且需要一个单元测试来确认它是否有效,我在哪里可以找到 24 位有符号整数及其相应的 32 位有符号值,以验证测试结果? :-) 再次感谢!
  • @smeeb 你可以选择任何随机的 24 位数字,将它们放入二进制补码到十进制转换器中,例如 this。然后您可以将相同的二进制数放入 3 字节数组中,上面的代码应将其转换为 32 位整数,其值与计算器完全相同。此代码将确保任何 24 位值在转换为 32 位格式时保留其值。
猜你喜欢
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多