web-dev-qa-db-ja.com

短い2バイトjava

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

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

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

しかし、正しい結果が得られません。署名された値が原因で問題がありますか?どうすればこの問題を解決できますか?

29
Nilesh

詳細に精通していなければ、ビットシフトで結び目を作る必要はありません。あなたはあなたを助けるためにByteBufferを使うことができます:

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

逆の場合も、ショートを入れてからバイトを取り出すことができます。

ちなみに、ビット単位の演算は、オペランドを少なくともintの幅に自動的に昇格させます。 「1バイトを7ビットを超えてシフトすることは許されない」という考えや、まとまりそうな他の噂は実際にはありません。

60
Neil Coffey

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

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

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

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

28
Lawrence Dol

他の答えはOKですが、私はタイプを強調したいと思います:

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

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

shortタイプは-32768から32767までの値を表すことができます。53328は簡潔にうまく格納できません。代わりにintを使用して、最大10までの符号なし値を格納できます。9 したがって、式を短くして、符号付きの値を取得するので、短くしないでください。

9
akarnokd

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

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

上記は0xFFCAを生成しますが、これは誤りです。これは、b2が負の値(バイト型が符号付きです!)であるためです。操作、それは0xFで左詰めされます!

したがって、必ず埋め込みバイトをマスクして、確実にゼロになるようにする必要があります。

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

より読みやすくエレガントな方法で、2バイトをshortに変換できます。

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

最初のバイトは最上位バイトです。

3