y_megane.log

日々の勉強や改善ネタの備忘。

リトルエンディアンとビッグエンディアンの違いを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#Javaでintをバイト配列に変換して出力してみる。

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 

ビッグエンディアンのため元のデータと同じ順序で出力される。

参考