web-dev-qa-db-ja.com

Javaリトルエンディアンまたはビッグエンディアンで整数を読み取りますか?

CプロセスからJavaにバイトストリームを送信しているので、私は尋ねます。 C側では、32ビット整数のLSBは最初のバイトで、MSBは4番目のバイトです。

だから私の質問は次のとおりです。Cプロセスから送信されたバイトを読み取るときのJava側では、 endian Java side?

追加の質問:Java側のエンディアンが送信されたものと同じでない場合、どうすればそれらを変換できますか?

92
hhafez

ネットワークバイトオーダー(ビッグエンディアン)を使用します。これはJavaが使用するものと同じです。Cの異なるトランスレーターについてはman htonsを参照してください。

63
Egil

私はここでグーグル経由でつまずき、Javaはビッグエンディアンです。

応答を読んで、バイトが実際にエンディアンの順序を持​​っていることを指摘したいのですが、「主流」のマイクロプロセッサしか扱っていないなら、Intel、Motorola、Zilogのように遭遇することはまずないでしょうUARTチップのシフト方向について合意し、バイトのMSBは2 ** 7であり、LSBはCPUで2 ** 0になることを強調しました(強調するためにFORTRANの電力表記を使用しましたこのものは何歳ですか:))。

この問題に遭遇したのは、20年以上前に10万ドルのインターフェイスハードウェアをMacコンピューターに交換したときのスペースシャトルビットシリアルダウンリンクデータです。 NASA Techブリーフがずっと前に公開されています。各バイトがビットストリームからシフトインされた後、ビットが反転された(テーブル[0x01] = 0x80など)256要素のルックアップテーブルを使用しました。

44
WB Greene

Javaには符号なし整数はありません。すべての整数は符号付きでビッグエンディアンです。

C側では、各バイトの先頭にLSBがあり、MSBが左側にあります。

LSBを最下位ビットとして使用しているようですね。 LSBは通常、最下位バイトを表します。 エンディアンネス はビットベースではなく、バイトベースです。

符号なしバイトからJava整数に変換するには:

int i = (int) b & 0xFF;

Byte []の符号なし32ビットリトルエンディアンからJava long(頭の上から、テストなし))に変換するには:

long l = (long)b[0] & 0xFF;
l += ((long)b[1] & 0xFF) << 8;
l += ((long)b[2] & 0xFF) << 16;
l += ((long)b[3] & 0xFF) << 24;
18
Jonas Elfström

一部のバイトをJavaのintに直接マップする(直接の非API)方法がないため、これがJavaの何かに影響を与える方法はありません。

これを行うすべてのAPIまたは類似のAPIは、動作を非常に正確に定義するため、そのAPIのドキュメントを参照する必要があります。

11
Joachim Sauer

バイトを1つずつ読み取り、それらをlong値に結合します。そうすれば、エンディアンを制御でき、コミュニケーションプロセスは透過的になります。

3
Wouter Lievens

使用するプロトコルに適合する場合、DataInputStreamの使用を検討してください。動作は 非常に明確に定義されています です。

3
Ilja Preuß

前述のように、Javaは「ビッグエンディアン」です。つまり、メモリ(少なくともIntel CPU)を調べると、intのMSBは左側にあります。すべてのJava整数型の場合、符号ビットはMSBにもあります。
「リトルエンディアン」システムによって格納されたバイナリファイルから4バイトの符号なし整数を読み取るには、Javaで少し適応します。 DataInputStreamのreadInt()はビッグエンディアン形式を想定しています。
4バイトの符号なし値(HexEditで01 00 00 00として表示される)を値1の整数に読み込む例を次に示します。

 // Declare an array of 4 shorts to hold the four unsigned bytes
 short[] tempShort = new short[4];
 for (int b = 0; b < 4; b++) {
    tempShort[b] = (short)dIStream.readUnsignedByte();           
 }
 int curVal = convToInt(tempShort);

 // Pass an array of four shorts which convert from LSB first 
 public int convToInt(short[] sb)
 {
   int answer = sb[0];
   answer += sb[1] << 8;
   answer += sb[2] << 16;
   answer += sb[3] << 24;
   return answer;        
 }
0
Donald W. Smith