Java中的24到32位转换

时间:2016-04-14 19:13:08

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

我对一个名为OpenBCI的新物联网项目感兴趣,该项目基本上是一个用于阅读和处理脑电波和其他生物数据的开源脑电图。在他们的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值的重要性是什么?
  • 左位移(<<)的目的是什么?

第二部分也有点神秘:

if ((newInt & 0x00800000) > 0) {
    newInt |= 0xFF000000;
} else {
    newInt &= 0x00FFFFFF;
}
  • 为什么newInt & 0x008000000x00800000的重要性是什么?
  • 为什么if-else基于上述操作的积极与非阴性结果?
  • 0xFF0000000x00FFFFFF的重要性是什么?

我猜这个功能正在进行大量的手工操作和魔术,我想更好地理解!

1 个答案:

答案 0 :(得分:8)

  

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

24位/ 8位= 3字节

  

0xFF值有什么意义?

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

  

左位移位(&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&gt;)的目的是什么?

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

  

为什么newInt&amp; 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填充第4个和最后一个字节的原因( 0xFF)使用OR运算符 如果它已经是正数,则第四个字节可以是0x00,后面的3个字节与原始的24位值相同 - 通过使用0x00FFFFFF进行屏蔽来实现。