2个字节来缩短java

问题描述 投票:28回答:5

我正在读取来自serialport的133长度数据包,最后2个字节包含CRC值,2个字节值我使用java制作单个(我认为)。这就是我所做的,

short high=(-48 & 0x00ff);
short low=80;

short c=(short) ((high<<8)+low);

但是我没有得到正确的结果,是因为签名有问题吗?我怎么能解决这个问题,请帮我解决这个问题

java type-conversion byte core short
5个回答
58
投票

请记住,如果您对细节不太熟悉,则不必将自己束缚在比特移位中。您可以使用ByteBuffer来帮助您:

ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(firstByte);
bb.put(secondByte);
short shortVal = bb.getShort(0);

反之亦然,你可以放一个短,然后拉出字节。

顺便说一句,按位运算自动将操作数提升到至少int的宽度。实际上并没有“不允许超过7位的字节转换”这一概念以及其他似乎正在转向的谣言。


26
投票

将流中的字节值转换为Java中的数值时,必须非常小心使用符号扩展。有一个带负数的陷阱(值来自(无符号)128-255)。

试试这个(如果hi和lo是任何Java整数类型,它都有效):

short val=(short)(((hi & 0xFF) << 8) | (lo & 0xFF));

在这些情况下,我发现最好明确括号。


9
投票

其他答案还可以,但我想强调一下这种类型:

short high=(-48 & 0x00ff);
short low=80;

int c= ((high & 0xFF) << 8) | (low & 0xFF);

short类型可以表示介于-32768到32767之间的值.53328不能简单地存储,使用int代替,因为它允许你存储无符号值~109所以不要将表达式向下转换为短,因为它会净化你签字价值。


6
投票

尝试连接字节时会发生这种情况(非常微妙)

byte b1 = (byte) 0xAD;
byte b2 = (byte) 0xCA;
short s = (short) (b1<<8 | b2);

以上产生0xFFCA,这是错误的。这是因为b2是负数(字节类型是有符号的!),这意味着当它将按位转换为int类型时操作,它将被填充为0xF!

因此,您必须记住屏蔽填充的字节,以便它们肯定为零:

short s = (short) (b1<<8 | b2 & 0xFF);

2
投票

您可以以更易读和更优雅的方式将2个字节转换为short。

short s = ByteBuffer.wrap(new byte[]{0x01, 0x02}).getShort();
// now s equals 258 = 256 + 2

第一个字节是最重要的字节。

© www.soinside.com 2019 - 2024. All rights reserved.