Java:将整数拆分为2个字节,然后再将它们组合成一个整数

时间:2013-08-15 07:00:32

标签: java bytearray

我目前正在开发一个项目,通过串口将数据从java应用程序发送到arduino。

我遇到的问题如下,我需要将一个Integer拆分为2个字节,然后将它们组合成Arduino中的Integer。但另一种方式(Arduino-> java)只会给我带来麻烦。 arduino部分并不那么难,就像魅力一样,但是尽管我查看了已经发布在这里的相关问题和答案,但我还是不能弄清楚如何将字节正确地组合成一个int。

以下是拒绝使用的java代码:

int in = 500;
byte[] data = new byte[2];

data[0] = (byte)(in & 0xFF);
data[1] = (byte)((in >> 8) & 0xFF);

int res = data[0] | (data[1] << 8);

我从中得到的控制台打印出来是:

data[0] = -12  
data[1] = 1  
res = -12

但我需要res为500!

4 个答案:

答案 0 :(得分:16)

Java使用签名字节(C,C ++,C#与 unsigned 操作),因此您应该处理补充表示(对于负值):

int in = 500; 
byte[] data = new byte[2]; // <- assuming "in" value in 0..65535 range and we can use 2 bytes only

data[0] = (byte)(in & 0xFF);
data[1] = (byte)((in >> 8) & 0xFF);

int high = data[1] >= 0 ? data[1] : 256 + data[1];
int low = data[0] >= 0 ? data[0] : 256 + data[0];

int res = low | (high << 8);

答案 1 :(得分:5)

问题出在这里:

int res = data[0] | (data[1] << 8);

|运算符需要int个操作数,而data[0]正在从byte升级为int。但由于byteint都是签名类型,因此该促销通过符号扩展将字节-12转换为整数-12 ....

最简单的解决方法是:

int res = (data[0] & 0xff) | ((data[1] & 0xff) << 8);

这里还有另一个问题。通常,您不能将int表示为2个字节。 int类型为32位宽,需要4个字节...来表示整个范围。

答案 2 :(得分:2)

另一种可能性就是使用NIO

ByteBuffer buf = ByteBuffer.allocate(2);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putShort(500);
byte[] result = buf.array(); // [-12, 1]

buf = ByteOrder.wrap(result);
buf.order(ByteOrder.LITTLE_ENDIAN);
short res = buf.getShort(); // 500

这有以下优点:

  • 与Java IO集成 - 您无需获取阵列 - 您可以直接将其传递给频道。
  • 明确的订购规范
  • 自Java 1.4以来它位于标准库中

答案 3 :(得分:-1)

如果你已经使用了番石榴(你应该这样做),this problem is already solved.