在java中将两个字节(一个正数和另一个负数)组合成short

Posted

技术标签:

【中文标题】在java中将两个字节(一个正数和另一个负数)组合成short【英文标题】:Combine two bytes (one positive and another negative ) into short in java 【发布时间】:2016-06-03 07:10:07 【问题描述】:

我正在尝试将我的 C++ 项目移植到 java 中。 下线我必须从串口读取一些字节并将两个字节组合成短的。使用下面的代码可以优雅地工作。

               ByteBuffer bb = ByteBuffer.allocate(2);
                bb.order(ByteOrder.LITTLE_ENDIAN);

                bb.put(b1);
                bb.put(b2);
                  result = bb.getShort(0);

在 c++ 项目中,它们有 unsigned short 而不是 short(在 java 中我们没有 unsigned)。

So my above logic result does not align with C++ result for below case:-
 b1 = 106 ,  b2 = -1     c++ result = 150   and java = -150


 b1 =-6, b2 =   -1     506 in VC++ but -6 in java

However, if only first byte is negative then my result are similar :
b1 = -12 ,  b2 = 1     c++ result = 500   and java = 500

我想将我的结果与 c++ 对齐。任何建议和帮助都将不胜感激。

【问题讨论】:

你到底想要什么?您的 C++ 显然没有组合两个字节,但 java 这样做是正确的。如果我们不知道 C++ 逻辑,我们就无法知道如何做 java。 @ElderBug 在 c++ 中它们将两个字节组合成 unsigned short 但在 java 中 short 是有符号的......这是导致结果差异的原因吗? C++ 没有将两个字节组合成无符号短字节。至少不是以明显的方式。有一些你没有展示的逻辑。 【参考方案1】:

不要使用getShort(),而是使用getInt()

您的问题是最高有效位被解释为符号位,因为这是有符号短的情况。如果您扩展数据类型,使该位不再被视为符号位,您应该得到您想要的行为。

您可能需要填充缓冲区来执行此操作:

ByteBuffer bb = ByteBuffer.allocate(4);
bb.order(ByteOrder.LITTLE_ENDIAN);

bb.put(b1);
bb.put(b2);
bb.put(0);
bb.put(0);

result = bb.getInt(0);

编辑:如果只有 C++ 代码在做正确的事情,这工作,但正如上面的 cmets 所指出的,它不是(即它是不是简单地将两个字节组合成一个短字节。它还会对它们执行一些其他转换。

【讨论】:

它为 107,-2 提供 65131.. 预期为 661 我没有得到这个异常。你确定你使用的是上面的代码完全(包括参数0getInt?) 删除了该评论。但没有得到预期的结果。 根据上述编辑,您需要发布 C++ 代码执行的实际逻辑。上面的代码实际上是在获取输入并将字节组合成一个无符号短。 C++ 代码没有这样做。【参考方案2】:

java -6 (0xFFFA) 是正确的,C++ 506 (0x01FA) 不是。 0xFA。好像你打错了 -1:1 或 - -1。

【讨论】:

以上是关于在java中将两个字节(一个正数和另一个负数)组合成short的主要内容,如果未能解决你的问题,请参考以下文章

Java基础知识

java加减的二进制实现

如何在 Swift 中将十六进制转换为有符号浮点数?适用于正数但不适用于负数

在 Java 中将 long 转换为字节

字节/字符——输入/输出流

原码 补码 反码