8

DatagramSocket からの符号なしビットを解析しています。合計 24 ビット (または 3 バイト) が入ってきます。1 つの符号なし 8 ビット整数の後に 16 ビット符号付き整数が続きます。しかし、Java は符号付きバイト以外のものをバイト/バイト配列に保存することはありませんか? Java がこれらの値を取り込むとき、最後の 8 番目のビットは失われますか?

DatagramSocket serverSocket = new DatagramSocket(666);
        byte[] receiveData = new byte[3]; <--Now at this moment I lost my 8th bit

        System.out.println("Binary Server Listing on Port: "+port);

        while (true)
        {
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receivePacket);
            byte[] bArray = receivePacket.getData();
            byte b = bArray[0];

        }

ここに画像の説明を入力

この 8 番目のビットを 1 バイトに変換したため、失われましたか? 3 バイトのバイト配列を初期化したのは間違っていましたか?

4

3 に答える 3

12

Java がこれらの値を取り込むとき、最後の 8 番目のビットは失われますか?

いいえ、設定すると負の値になります。

したがって、0 から 255 の間の値を取得するには、次のようなものを使用するのが最も簡単です。

int b = bArray[0] & 0xff;

最初にbyteが に昇格し、int符号拡張されて、元の値の上位ビットが 1 の場合、先行する 25 ビットが 1 になります。次に& 0xff、最初の 24 ビットを再び取り除きます :)

于 2013-01-02T20:58:12.630 に答える
9

いいえ、8 番目のビットは失われません。しかし残念なことに、Java には 2 つの「機能」があり、そのような値を処理するのが合理的ではありません。

  • そのプリミティブ型はすべて署名されています。
  • プリミティブ型をより大きなサイズの別のプリミティブ型に「ラップ解除」する場合 (たとえば、ここでのケースのように abyteから anを読み取るint場合)、「下位型」の符号ビットが拡張されます。

つまり、たとえば、 byte を読み取る0x80と、バイナリで次のように変換されます。

1000 0000

整数として読み取ると、次のようになります。

1111 1111 1111 1111 1111 1111 1000 0000
                              ^
                              This freaking bit gets expanded!

あなたが本当に望んでいたのに対し:

0000 0000 0000 0000 0000 0000 1000 0000

つまり、整数値 128 です。したがって、マスクする必要があります。

int b = array[0] & 0xff;

1111 1111 1111 1111 1111 1111 1000 0000 <-- byte read as an int, your original value of b
0000 0000 0000 0000 0000 0000 1111 1111 <-- mask (0xff)
--------------------------------------- <-- anded, give
0000 0000 0000 0000 0000 0000 1000 0000 <-- expected result

悲しいけれど事実です。

より一般的には、多くのバイト指向のデータを操作したい場合は、ByteBufferを見ることをお勧めします。これは非常に役立ちます。残念ながら、これはビットマスク操作からあなたを救うことはできません。それは、指定された量のバイトを一度に (プリミティブ型として) 読み取りやすくするだけです。

于 2013-01-02T21:03:19.190 に答える
2

Java では、バイト (および short、int、long) は符号付きの数値データ型のみです。ただし、これは、データを符号なしバイナリ データとして扱う場合にデータが失われることを意味するものではありません。あなたの図が示すように、10000000-128符号付き10進数です。バイナリ データを扱っている場合は、バイナリ形式として扱うだけで問題ありません。

于 2013-01-02T20:59:13.923 に答える