我试图简化一些用于解码文件中数据的代码,并且我已经编写了一个测试用例来说明问题。
给定0xFe
和0xFF
两个字节,我希望将其读作0xFFFE
(65534),
现有代码
headerBuffer.get() & 0xff + (headerBuffer.get() & 0xff) * 256
我想,如果我将缓冲区字节顺序设为小端,我可以通过读取短路来得到相同的结果。但是我没有得到相同的结果,为什么不呢?
headerBuffer.getShort();
public void testReadingOfShort() {
ByteBuffer headerBuffer = ByteBuffer.allocate(2);
headerBuffer.order(ByteOrder.LITTLE_ENDIAN);
headerBuffer.put((byte) 0xFE);
headerBuffer.put((byte)0xFF);
headerBuffer.position(0);
int format = headerBuffer.get() & 0xff + (headerBuffer.get() & 0xff) * 256;
headerBuffer.position(0);
int formatNew = headerBuffer.getShort();
System.out.println("Format:"+format+"("+ Hex.asHex(format)+")"+":FormatNew:"
+formatNew+"("+Hex.asHex(formatNew)+")");
}
输出
Format:65534(0xfffe):FormatNew:-2(0xfffffffffffffffe)
答案 0 :(得分:3)
你得到的价值相同。将short
分配到此行的int
时会出现问题:
int formatNew = headerBuffer.getShort();
执行此操作时,Java会执行签名扩展,以确保short
中的数值转换为int
中的相同数值。在你的情况下,那是-2。
-2作为short
的表示形式为0xFFFE
,而int
表示形式为0xFFFFFFFE
。换句话说,short
的符号位被复制到int
的附加高位。
您可以通过不将short
分配给int
来解决此问题。您还需要确保Hex.asHex
对short
有适当的重载,否则当formatNew
作为参数传递时,会发生相同的转换。
或者,如果您希望将short
的值视为未签名,并将其分配给int
,则可以使用0xFFFF
屏蔽结果,如下所示:< / p>
int formatNew = headerBuffer.getShort() & 0xFFFF;
答案 1 :(得分:0)
我的假设是,在Hex
课程中,您使用.asHex()
方法将short
作为参数,其中包含以下内容:
int value = (int) argument;
运气好。如果您从一个整数类型“向上转换”到另一个整数类型,则符号位(如果存在) 被携带。这意味着如果你尝试将短0xfffe转换为int,你将不会得到0x0000fffe但是...... 0xfffffffe。因此你的结果。
如果你想把它作为无符号值投射,你必须掩盖它,如下所示:
int value = (int) argument & 0xffff;
答案 2 :(得分:0)
您可以简单地获得所需的值
int formatNew = headerBuffer.getShort() & 0xFFFF;
或者,如果您使用Java 8:
int formatNew = Short.toUnsignedInt(headerBuffer.getShort());
这将基本上丢弃int
中不属于short
的所有位。但是,它不会减轻您的责任,即仔细检查您希望无符号值的位置,以及如何在相应的上下文中处理(自然)签名值。