「ビッグ」と「リトル」という名前だけでは、どちらがどちらだったか迷います。 覚えるべき違いは一つです。複数バイトの数値を、メモリの低いアドレスからどの順番で置くかです。
1. まずは 0x12345678 を4つに分ける
32ビットの16進数 0x12345678 は、1バイトずつに分けると次の4つになります。
左端の 12 は数値への影響が最も大きい最上位バイト(MSB)、
右端の 78 は最も小さい最下位バイト(LSB)です。
エンディアンによって変わるのは、この4バイトをメモリへ置く順番です。
ビッグエンディアン
大きい側の 12 から置く
リトルエンディアン
小さい側の 78 から置く
Big-endian:大きい桁を含むバイトが先。
Little-endian:小さい桁を含むバイトが先。
2. 同じ数値でも、メモリ上の見え方が違う
| アドレス | ビッグエンディアン | リトルエンディアン |
|---|---|---|
0x1000 | 0x12(MSB) | 0x78(LSB) |
0x1001 | 0x34 | 0x56 |
0x1002 | 0x56 | 0x34 |
0x1003 | 0x78(LSB) | 0x12(MSB) |
どちらも表している数値は 0x12345678 です。
CPUが自分の方式に従って読み出す限り、計算結果に違いはありません。
問題になるのは、別の機器との通信、バイナリファイル、メモリダンプなど、バイト列そのものを扱う場面です。
3. ビットの順番を逆にする話ではない
エンディアンは通常、バイトを並べる順番の話です。 各バイトの中のビットまで逆にするわけではありません。
0x12 はどちらの方式でも 0x12 のままです。ビットを逆順にした
0x48 へ変わるわけではありません。
また、16進数を紙に書く順番が変わるという意味でもありません。
論理上の値は常に 0x12345678 であり、違うのはメモリや通信データに分解したときの配置です。
4. 浮動小数点数も、最後はバイト列になる
IEEE 754の単精度浮動小数点数 1.0 の32ビット表現は 0x3F800000 です。
このビットパターン自体は同じでも、メモリに見えるバイト列は変わります。
センサーデータや組み込み機器のレジスタを読むときに、値が極端に大きい、極端に小さい、あるいは意味のない値になった場合は、型だけでなくエンディアンも確認します。
5. どこで出会うのか
- CPUとメモリ:x86やx64では一般にリトルエンディアンが使われます。
- ネットワーク:IPなどで使うネットワークバイトオーダーはビッグエンディアンです。
- バイナリファイル:ファイル形式ごとにバイト順が定められています。
- 組み込み機器:CPU、通信プロトコル、周辺ICで方式が異なることがあります。
- メモリダンプ:画面に並んだバイトから元の数値を組み立てるときに必要です。
「このCPUはどちらか」だけで判断せず、いま読んでいるデータの仕様を確認するのが確実です。
6. バイト列から見分ける
既知の値を一つ用意すると判別しやすくなります。16ビット値 0x1234 を保存して、低いアドレスから2バイトを確認します。
通信データやファイルなら、仕様書に byte order、endianness、MSB first、 LSB first といった記述がないか探します。ただし「MSB first」はビット転送順を指す場合もあるため、対象がバイトかビットかも確認します。
7. 読み違えを防ぐ確認項目
- 一つの値は何バイトか
- 先頭は低いアドレスか、通信上の先頭か
- 最上位バイトと最下位バイトのどちらが先か
- 符号付き整数、符号なし整数、浮動小数点数のどれか
- 仕様に沿って変換した後で、現実的な値になるか
16進数と2進数の対応を確認したいときは、M.A.L.の基数変換ツールも利用できます。
Radix Converterを開く →8. 一文で覚える
エンディアンとは、最上位バイトと最下位バイトのどちらを低いアドレスへ置くかという決まりです。