エンディアン
2 バイト以上のデータをメモリやファイルに格納する際の、バイトの並び順を定める規約
エンディアンとは
エンディアン (endianness) は、2 バイト以上の数値をメモリやファイル、ネットワーク上に並べるときの「バイトの順序」を定める規約である。最上位バイトを先頭に置く方式をビッグエンディアン、最下位バイトを先頭に置く方式をリトルエンディアンと呼ぶ。
同じ数値 0x12345678 (4 バイト) でも、並び順は方式によって正反対になる。
数値: 0x12345678 (10 進では 305419896)
ビッグエンディアン (上位バイトが先)
アドレス: +0 +1 +2 +3
バイト: 12 34 56 78
リトルエンディアン (下位バイトが先)
アドレス: +0 +1 +2 +3
バイト: 78 56 34 12
人間が数字を左から書く感覚に近いのはビッグエンディアンだが、x86 / x86-64 や多くの ARM 構成はリトルエンディアンを採用している。このため「直感的でない並び順」が実務の標準になっている点が、つまずきの最初の一歩になる。
なぜ実務で問題になるのか
単一のマシン内で完結する処理なら、エンディアンを意識する場面はほとんどない。CPU が一貫した方式で読み書きするため、プログラマからは透過的に見える。問題が表面化するのは、バイト列が異なる環境をまたいで移動するときである。
- 異なる CPU アーキテクチャ間でバイナリデータを交換する
- ファイルフォーマットやネットワークプロトコルを自前でパースする
- メモリダンプやパケットキャプチャを直接読む
ネットワーク通信では歴史的にビッグエンディアンが標準とされ、これを「ネットワークバイトオーダー」と呼ぶ。一方、送受信するホストの多くはリトルエンディアンであるため、ソケット API では htons / htonl (host to network) や ntohs / ntohl (network to host) といった変換関数でバイト順を明示的にそろえる。この変換を忘れると、ポート番号や IP アドレスが化けるという典型的なバグになる。
エンディアンの確認方法
自分が動かしている環境がどちらかは、1 つの整数を 1 バイトずつ覗けば判定できる。
#include <stdio.h>
int main(void) {
unsigned int x = 1; // 0x00000001
unsigned char *p = (unsigned char *)&x;
// 先頭バイトが 1 ならリトルエンディアン
printf("%s\n", p[0] == 1 ? "little-endian" : "big-endian");
return 0;
}
0x00000001 の先頭バイトが 01 ならリトルエンディアン、00 ならビッグエンディアンである。
ビッグエンディアンとリトルエンディアンの比較
| 観点 | ビッグエンディアン | リトルエンディアン |
|---|---|---|
| 並び順 | 上位バイトが先頭 | 下位バイトが先頭 |
| 主な採用例 | ネットワークプロトコル、一部の RISC、Java の class ファイル形式 | x86 / x86-64、多くの ARM 構成 |
| ダンプの読みやすさ | 人間の数字表記に近い | 慣れないと逆順に見える |
| 型のサイズ拡張 | 先頭がずれる | 先頭アドレスが変わらず拡張しやすい |
Java を「ビッグエンディアンの処理系」と一括りにするのは正確ではない。仕様がビッグエンディアンで固定しているのは class ファイル形式の多バイトデータ項目と java.nio.ByteBuffer の初期バイト順であり、JVM が実行中にメモリ上でどう並べるかは仕様に規定がなく実装依存である。
どちらが優れているという絶対的な優劣はない。リトルエンディアンは「同じアドレスから読み始めても型の幅を変えやすい」という実装上の利点があり、ビッグエンディアンは「人間が読んだときの直感性」と「プロトコル標準としての一貫性」で支持されてきた。
よくある落とし穴
- 変換忘れ: ネットワーク送受信や異機種間のファイル交換で
hton*/ntoh*相当の変換を省くと、値が逆順に化ける。単一環境のテストでは再現しないため発見が遅れやすい。 - バイナリの直接比較: バイト列をそのまま比較・ハッシュ化すると、エンディアンの違うシステム同士で不一致になる。交換用フォーマットでは並び順を仕様で固定する。
- キャストでの覗き見:
intをchar*にキャストして 1 バイトずつ扱うコードは、エンディアン依存になりやすい。移植性を保つにはビットシフトで明示的に組み立てる。
こうした事故を避ける最も確実な方法は、自前でバイト列を組み立てず、並び順を仕様で固定したシリアライズ形式に委ねることである。データのメモリ上の並びについては メモリレイアウト、相互運用を前提とした変換の考え方は エンコーディングとシリアライゼーション や Protocol Buffers もあわせて参照してほしい。
この記事は役に立ちましたか?
関連用語
関連する記事
月曜朝イチのコードが金曜夕方より美しい理由
週の始まりに書くコードと終わりに書くコードでは、品質に差が出やすいものです。その背景と、コード品質を週を通じて維持するための読書習慣を考えます。
ゼロから作る Deep Learning シリーズの読む順番 - 全 6 巻の内容と選び方を整理
ゼロから作る Deep Learning シリーズ全 6 巻 (基礎 / 自然言語処理 / フレームワーク / 強化学習 / 生成モデル / LLM) の読む順番を解説。各巻の内容 / 発売年 / 前提知識を一覧表で整理し、目的別にどの巻から読むべきかを案内します。
ディープラーニング本の選び方 - 原理 / 理論 / 実装 / 数学の 4 系統で整理 (2026 年 8 月時点)
ディープラーニング本の選び方を 4 系統 (原理を手で理解する本 / 理論を体系的に学ぶ本 / フレームワーク実装本 / 数学を補う本) に整理。2026 年 8 月時点の定番書を目的別 / レベル別に紹介し、賞味期限の見極め方も解説します。