私はシリアルポートから133長のパケットを読み取っています。最後の2バイトにはCRC値が含まれています。2バイトの値はJavaを使用して単一(短いと思います)にしました。これは私がやったこと、
short high=(-48 & 0x00ff);
short low=80;
short c=(short) ((high<<8)+low);
しかし、正しい結果が得られません。署名された値が原因で問題がありますか?どうすればこの問題を解決できますか?
詳細に精通していなければ、ビットシフトで結び目を作る必要はありません。あなたはあなたを助けるために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ビットを超えてシフトすることは許されない」という考えや、まとまりそうな他の噂は実際にはありません。
ストリームからバイト値をJava=の数値に変換するときは、符号拡張に注意する必要があります。負の数((符号なし)128-255の値)のトラップがあります。
これを試してください(hiとloがいずれかである場合に機能しますJava整数型):
short val=(short)(((hi & 0xFF) << 8) | (lo & 0xFF));
これらの場合、括弧で明示するのが最善だと思います。
他の答えはOKですが、私はタイプを強調したいと思います:
short high=(-48 & 0x00ff);
short low=80;
int c= ((high & 0xFF) << 8) | (low & 0xFF);
short
タイプは-32768から32767までの値を表すことができます。53328は簡潔にうまく格納できません。代わりにint
を使用して、最大10までの符号なし値を格納できます。9 したがって、式を短くして、符号付きの値を取得するので、短くしないでください。
これは、バイトを連結しようとすると発生します(非常に微妙)
byte b1 = (byte) 0xAD;
byte b2 = (byte) 0xCA;
short s = (short) (b1<<8 | b2);
上記は0xFFCAを生成しますが、これは誤りです。これは、b2が負の値(バイト型が符号付きです!)であるためです。操作、それは0xFで左詰めされます!
したがって、必ず埋め込みバイトをマスクして、確実にゼロになるようにする必要があります。
short s = (short) (b1<<8 | b2 & 0xFF);
より読みやすくエレガントな方法で、2バイトをshortに変換できます。
short s = ByteBuffer.wrap(new byte[]{0x01, 0x02}).getShort();
// now s equals 258 = 256 + 2
最初のバイトは最上位バイトです。