33

シリアルポートから133の長さのパケットを読み取っています。最後の2バイトには、CRC値が含まれています。2バイトの値は、Javaを使用してシングル(短いと思います)にしました。これは私がしたことです、

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

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

しかし、正しい結果が得られません。署名された値が原因で問題が発生しますか?どうすればこの問題を解決できますか、plzは私が困っているのを助けます

4

6 に答える 6

67

詳細にあまり詳しくない場合は、ビットシフトで結び目を作る必要はありません。ByteBufferを使用して、次のことを支援できます。

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

逆に、shortを入れてから、バイトを引き出すことができます。

ちなみに、ビット演算は、オペランドを少なくともintの幅に自動的にプロモートします。「7ビットを超えるバイトをシフトすることは許可されていない」という概念や、流行しているように見える他の噂は実際にはありません。

于 2009-04-10T06:06:09.907 に答える
32

Java でバイト値をストリームから数値に変換する場合、符号拡張には十分注意する必要があります。負の数 ((符号なし) 128 ~ 255 の値) のトラップがあります。

これを試してください(hiとloがJava整数型の場合に機能します):

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

これらの場合、括弧で明示するのが最善だと思います。

于 2009-04-10T06:40:54.800 に答える
12

これは、バイトを連結しようとしたときに発生します (非常に微妙)。

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

上記は 0xFFCA を生成しますが、これは間違っています。これは、b2 が負であるためです (バイト型は符号付きです!)。操作すると、左に 0xF が埋め込まれます!

したがって、パディングされたバイトが確実にゼロになるようにマスクアウトすることを忘れないでください。

short s = (short) (b1<<8 | b2 & 0xFF);
于 2016-07-06T15:43:48.237 に答える
10

他の答えは問題ありませんが、タイプに重点を置きたいと思います:

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

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

short型は -32768 から 32767 の間の値を表すことがintできます 。価値。

于 2009-07-08T14:18:43.293 に答える