在Java中处理24到32位的转换
我对一个名为OpenBCI的新物联网项目感兴趣,该项目基本上是一个开源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
值的意义是什么李>- 左位移位(
<<
)的目的是什么李>
第二部分也有点神秘:
if ((newInt & 0x00800000) > 0) {
newInt |= 0xFF000000;
} else {
newInt &= 0x00FFFFFF;
}
- 为什么
newInt & 0x00800000
?0x00800000
的意义是什么李> - 为什么
if-else
基于上述操作的正结果与非负结果李> 0xFF000000
和0x00FFFFFF
的意义是什么李>
我想这个函数中有很多手工操作和魔法,我希望能更好地理解
# 1 楼答案
24位/8位=3字节
这有点像面具^二进制的{}。在这种情况下,它被用作将字节值转换为int的快速方法
一旦在前一条指令中检索到int值,它将向左移动16位,以获取int的第三个字节的位置(从右开始计数)。这是因为字节数组以big-endian格式存储字节,其中MSB位于第一位。下一个字节仅移位8位以占据第二个字节的位置,而最后一个字节根本不需要移位,因为它已经位于第一个字节的位置
嗯
0x80
是另一个位掩码,用于获取某个字节的MSB0x00800000
对应于第三个字节的MSB(即byteArray[0]
中在上一个过程中被左移了16位的字节)。这也对应于整个24位值的MSB确定24位值的MSB是1还是0将告诉我们在two's complement符号中它分别是负数还是正数
如果这个数字在24位表示中是负数,我们还希望它在2的补码中作为32位值是负数,这就是为什么我们必须使用OR运算符用
0b11111111
(0xFF)填充第四个字节和最后一个字节如果已经是正数,那么第四个字节可以是0x00,下面的3个字节与原始的24位值相同——通过使用
0x00FFFFFF
屏蔽来实现