【问题标题】:Java: Splitting Integer into 2 Bytes and then combining them again into an IntegerJava:将整数拆分为 2 个字节,然后将它们再次组合成一个整数
【发布时间】:2013-08-17 08:26:54
【问题描述】:

我目前正在开发一个项目,该项目通过串行端口将数据从 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!

【问题讨论】:

  • 一个 int 由 4 个字节组成...
  • 如果我理解正确的话,你想在data[0]中存储5,在data[0]中存储0。其他0呢。不应该是byte[3]吗?
  • 问题是你沮丧地使用byte[]。如果您使用short[]int[],它将按预期工作

标签: java arrays integer


【解决方案1】:

Java 使用 有符号字节(C、C++、C# 使用 无符号 字节),因此您应该注意 补码表示(对于负值):

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);

【讨论】:

  • 谢谢,我找到了最佳答案。如果可以的话,我会给 +2。
【解决方案2】:

问题发生在这里:

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 个字节 ... 来表示整个范围。

【讨论】:

  • 关于您的编辑:是的,我知道,但我不需要整数的整个范围,因为 Arduino 上的整数是 2 个字节。我不打算发送任何大于 2 个字节可以表示的内容。
  • 您应该考虑改用 Java short
  • 是的,我也是这么想的,但我想看看它是否也适用于整数。
  • 对于shortint,您将遇到相同的问题(wrt 符号扩展)。唯一的区别是您需要将表达式转换为short。 Java 的按位&amp;|^ 运算符仅定义为int, int -&gt; intlong, long -&gt; long
【解决方案3】:

另一种可能性就是使用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 起就在标准库中

【讨论】:

    【解决方案4】:

    如果你已经在使用 Guava(你应该这样做),this problem is already solved.

    【讨论】:

      猜你喜欢
      • 2020-01-20
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多