Java 中的 24 位到 32 位转换

24- to 32-bit conversion in Java

我对一个名为 OpenBCI, which is basically an open source EEG for reading and processing brain waves and other biodata. In their docs they claim that the data transmitted over-the-air (via RFDuino) sends 24-bit data. To convert the 24-bit values into 32-bit signed integers, they suggest the following Java-friendly 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])
);

第二段也有点玄:

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

我想我想更好地理解此功能中的许多技巧和魔法!

Why is it safe to assume there are 3 bytes in the input?

24 位/8 位 = 3 字节

What is the significance of the 0xFF value?

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

What is the purpose of the left-bitshifting (<<)?

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

Why newInt & 0x00800000? What's the significance of 0x00800000?

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

Why the if-else based on postive vs. non-negative result of the above operation?

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

What is the significance of 0xFF000000 and 0x00FFFFFF?

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

进行掩码来实现