この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。出典を追加して記事の信頼性向上にご協力ください。(このテンプレートの使い方)
出典検索?: "エンディアン"
この記事には独自研究が含まれているおそれがあります。問題箇所を検証し出典を追加して、記事の改善にご協力ください。議論はノートを参照してください。(2016年7月)
.mw-parser-output .hatnote{margin:0.5em 0;padding:3px 2em;background-color:transparent;border-bottom:1px solid #a2a9b1;font-size:90%}
日付の表記方法については「#日付表現のエンディアン」をご覧ください。
エンディアン(英: endianness)あるいはバイトオーダ(byte order)は、コンピュータの記憶装置に複数バイト(多バイト)からなる数値を記憶する際の、各バイトの順序についての規則[1][2]。また、通信で複数バイトを扱う際の、送る順序についての規則。[注釈 1][3] コンピュータで扱う数値(やデータ)は、1バイトで表現されるもの以外に、2バイト、4バイト、8バイトなど複数バイト(多バイト)で表現されるものがある。一方、記憶装置は汎用化され、最小の1バイト単位でも扱えるように、1バイト毎に番地(アドレス)が連続して割り振られている。すると、多バイトの数値やデータの各バイトをどのような順序で記憶装置に格納するかについての規則は、いくつか種類(選択肢)があることになる。 まず主につかわれている種類を解説すると、特に、数値の1番小さい桁1バイト分を、1番大きいアドレスの記憶装置に配置し順に並べる規則はビッグエンディアンという。それと対称的に、数値の1番小さい桁1バイト分を、1番小さいアドレスの記憶装置に配置し順に並べる規則をリトルエンディアンという。[1][2] ビッグエンディアンを採用しているコンピュータやCPUとしては、IBMのメインフレーム(および互換機)、モトローラのMC68000(および後継)、サン・マイクロシステムズのSPARCなどがある。 リトルエンディアンを採用しているものとしては、DECのVAX、インテルのx86、Appleシリコン[注釈 2]、などがある。 エンディアンを切り替えられるバイエンディアン (bi-endian) のプロセッサとしては、PowerPCなどがある。なおARMアーキテクチャのコアは両モードをサポートするが、デフォルトの設定としてはリトルエンディアンとしており、ARM向けLinuxディストリビューションのほとんどはリトルエンディアンのみにしようと試みている[4]。 言語処理系などの仮想マシンの類では、プラットフォームに応じエンディアンを使い分ける設計のものもあれば、片方に寄せる設計のものもある。例えば、Java仮想マシンはプラットフォームを問わずビッグエンディアンである。 なおバイトオーダの種類の理論的な数(理論上の選択肢数)は、数学の順列の考え方で理解すればよく、階乗で計算でき[5]、2バイト数値では2!=2*1=2種類、4バイト数値では4!=24種類、8バイト数値では8!=40320種類もある。(理論上はこれだけあるが、ビッグエンディアンやリトルエンディアンが単純で使いやすく、他のややこしい順序をわざわざ選ぶ必然性は無いので、通常どちらかが使われている。)[注釈 3] 前節で説明した現実に使われている主要な2種に加えて、理論上は可能な他のバイトオーダの具体例の一部を示すため、4バイトの数値0x01234567を記憶するために、4バイトの連続した記憶装置に並べる例を下で提示する。16進数表記した上記数値の一番小さい桁の1バイト分は0x67であり、一番大きい桁の1バイト分は0x01である。表のアドレスは、左が小さいアドレス80で、右が大きいアドレス83を示すことに注意。 4バイト数値0x01234567の配置[1][2]アドレス80818283 下記は、記憶装置でのバイトオーダを表示し規則を簡易的に判定するプログラムの例である。C言語で書かれており、表と同じく左が小さいアドレスで、右が大きいアドレスで表示している。#include <stdint.h>#include <stdio.h>intisLittleEndian(void){ int i = 1; uint8_t *p = (uint8_t *) &i; return *p;}intmain(int argc, char *argv[]){ uint64_t i8 = 0x0123456789abcdef; uint32_t i4 = 0x01234567; uint16_t i2 = 0x0123; double d = -1.0/3.0; uint8_t *p; /* 8ByteOrder */ p = (uint8_t *) &i8; printf("8Byte Order %016lx\n", i8); printf(" on Memory |%02x|%02x|%02x|%02x|%02x|%02x|%02x|%02x|\n", *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7)); /* 4ByteOrder */ p = (uint8_t *) &i4; printf("4Byte Order %08x\n", i4); printf(" on Memory |%02x|%02x|%02x|%02x|\n", *p, *(p+1), *(p+2), *(p+3)); /* 2ByteOrder */ p = (uint8_t *) &i2; printf("2Byte Order %04x\n", i2); printf(" on Memory |%02x|%02x|\n", *p, *(p+1)); /* 8Byte Double Order */ p = (uint8_t *) &d; printf("DoubleOrder %lf == %le\n", d, d); printf(" on Memory |%02x|%02x|%02x|%02x|%02x|%02x|%02x|%02x|\n", *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7)); /* UTF8 strings */ p = (uint8_t *) "01?語\n"; printf("StringOrder %s", p); printf(" on Memory |%02x|%02x|%02x|%02x|%02x|%02x|%02x|%02x|%02x|%02x|%02x|\n", *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5), *(p+6), *(p+7), *(p+8), *(p+9), *(p+10)); if (isLittleEndian()) { printf("is LittleEndian\n"); } else { printf("is Not LittleEndian\n"); } return 0;} リトルエンディアン、日本語UTF-8のLinux環境での処理結果 8Byte Order 0123456789abcdef on Memory |ef|cd|ab|89|67|45|23|01。4Byte Order 01234567 on Memory |67|45|23|01。2Byte Order 0123 on Memory |23|01。DoubleOrder -0.333333 == -3.333333e-01 on Memory |55|55|55|55|55|55|d5|bf。StringOrder 01?語 on Memory |30|31|f0|9f|a5|ba|e8|aa|9e|0a|00。is LittleEndian 単一あるいは同種のコンピュータで閉じたシステムならば、通常は内部のエンディアンの相違も含めてあらかじめ調整や対策が施してあるので、問題となることはほぼ無い。一方、次のような場合ではエンディアンの相違が問題となり正常な動作をしないことがある。 TCP/IPプロトコルスタックでは、ビッグエンディアンに統一しており、それをネットワークバイトオーダという。この分野では、それに対し、各コンピュータのエンディアンをホストバイトオーダという。 画像や音声などのバイナリファイルにおいても、異なるコンピュータ間の互換性を確保するため、通常はエンディアンが規定される。 Unicodeにおいても、構成要素が多バイトとなるエンコーディング(主にUTF-16)では、エンディアンが問題となる。
概要
主に使われるバイトオーダビッグエンディアン(右)とリトルエンディアン(左)
理論上の可能性
ビッグエンディアン01234567
リトルエンディアン67452301
PDP-1123016745
非現実的な規則の一例45672301
判定プログラムの例
互換性・移植性
ネットワークを通してバイト単位でデータをやりとりする場合
異なるシステム間でバイナリファイルなどを交換する場合
異なるシステムにプログラムを移植する場合
構成するプロセッサが異なるマルチプロセッサ環境で共有メモリを使用する場合
Size:23 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)』
担当:undef