リトルエンディアンとビッグエンディアンの違いをC#とJavaで実験
仕事でバイナリデータの読み書きをする際に自作ツールとメーカーツールで結果が異なったため、その原因調査の一貫として勉強したことの備忘。
バイトオーダ
多バイトのデータをどういう順番でメモリに格納するか。
プロセッサによって異なる。
Intelはリトルエンディアン。
JVMはビッグエンディアン。
ネットワークにおいても多バイトデータをどう通信するか、バイトオーダを決める必要がある。
TCP/IPはビッグエンディアン。
リトルエンディアン
下位ビットを低位のアドレスに格納する。順序が逆になる。
バイト列: 0x0123456789ABCDEF
メモリ配置: [EF, CD, AB, 89, 67, 45, 34, 01]
キャストする場合、下位のnバイトを読めばいいので効率がいい。
上のバイト列(8バイト)を4バイトにキャストする場合、メモリの0番地〜3番地を読めばよい。
ビッグエンディアン
上位ビットを低位のアドレスに格納する。
バイト列: 0x0123456789ABCDEF
メモリ配置: [01, 23, 45, 67, 89, AB, CD, EF]
キャストする場合上位のnバイトを読むためにオフセットが必要になる。
実験
C#
int data = 0x0123ABCD; byte[] byteArray = BitConverter.GetBytes(data); foreach(byte b in byteArray) Console.Write($"{b:X2} ");
出力結果 CD AB 23 01
リトルエンディアンのため元のデータと逆順で出力される。
Java
int data = 0x0123ABCD; byte[] byteArray = ByteBuffer.allocate(4).putInt(data).array(); for (byte b : byteArray) { System.out.printf("%02X ", b);
出力結果 01 23 AB CD
ビッグエンディアンのため元のデータと同じ順序で出力される。