Java 中的 LSB/MSB 处理

2022-09-03 09:18:51

如果我必须像0x118那样处理要以字节形式存储的值,如何拆分LSB和MSB?

我正在尝试以下方式...我不认为这是正确的方式:

value = 0x118;  

以字节为单位存储...

result[5] = (byte) value;  
result[6] = (byte)(value << 8);  
...

正确的方法是什么?


答案 1

这将这样做:

result[5] = (byte) (value & 0xFF);           // Least significant "byte"
result[6] = (byte) ((value & 0xFF00) >> 8);  // Most significant "byte"

我通常使用位面罩 - 也许不需要它们。第一行选择下八位,第二行选择上八位,并将位八位向右移动。这等于除以 28


这是背后的“诀窍”:

  (I) LSB

  01010101 10101010        // Input
& 00000000 11111111        // First mask, 0x00FF
  -----------------
  00000000 10101010        // Result - now cast to byte

  (II) MSB

  01010101 10101010        // Input
& 11111111 00000000        // Second mask, 0xFF00
  -----------------
  01010101 00000000        // Result - 
  >>>>>>>>                 // "Shift" operation, eight positions to the right
  -----------------
  00000000 01010101        // Result - now cast to byte

总而言之,请进行以下计算:

 byte msb = result[6];
 byte lsb = result[5];
 int result = (msb << 8) + lsb;    // Shift the MSB bits eight positions to the left.

答案 2

在今天的Java版本中,没有必要手动执行此操作。而且你不应该这样做,因为它很容易插入错误。

只需使用:

short value = 0x118;
ByteBuffer.wrap(result).order(ByteOrder.LITTLE_ENDIAN).putShort(5, value);

对于此任务。类 ByteBuffer 提供了一些方法,用于根据需要将所有基元数据类型(按小端序或大字节序字节序排列)。它还提供了一种使用隐含位置放置异构值序列的方法:

ByteBuffer.wrap(result) // default big endian, start a offset 0
  .put(byteValue).putInt(123456).putShort(value)
  .order(ByteOrder.LITTLE_ENDIAN) // change for next values
  .putInt(400).putShort(value);

或者一种更有效的方法来处理相同类型值的序列:

ByteBuffer.wrap(result).order(ByteOrder.LITTLE_ENDIAN)
  .asShortBuffer().put(shortValue1).put(shortValue2).put(shortValue3);

当然,您也可以回读该值:

System.out.printf("0x%x%n",
  ByteBuffer.wrap(result).order(ByteOrder.LITTLE_ENDIAN).getShort(5));