2022.09.15

IT用語

エンディアン(endian)

エンディアンは、2つ以上のバイトデータを並べる順番のことです。

並べる順番によって、ビッグエンディアンリトルエンディアンなどと呼びます。

ビッグエンディアンは、最上位バイトから順番に格納するものです。

例えば、2バイト整数1025(16進数で0x0401)をビッグエンディアンで格納する場合、'0x40'、'0x01'の順番で格納されます。4バイト整数0xabcd1234を格納する場合、'0xab'、'0xcd'、'0x12'、'0x34'の順番になります。

アドレス +0 +1
バイトの値 0x40 0x01
アドレス +0 +1 +2 +3
バイトの値 0xab 0xcd 0x12 0x34

リトルエンディアンは、最下位バイトから順番に格納するものです。

バイト整数1025(16進数で0x0401)をリトルエンディアンで格納する場合、'0x01'、'0x40'の順番で格納されます。4バイト整数0xabcd1234を格納する場合、'0x34'、'0x12'、'0xcd'、'0xab'の順番になります。

アドレス +0 +1
バイトの値 0x01 0x04
アドレス +0 +1 +2 +3
バイトの値 0x34 0x12 0xcd 0xab

エンディアン確認用のJavaソースコード その1

整数1025(16進数で0x0401)を2バイト整数であるshort型変数に代入し、その値をbyte型配列に格納するソースコードです。

配列に格納した値は、10進数でコンソール出力しています。

Short2Bytes.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class Short2Bytes {
	public static void main( String[] args ) {
		// 結果を格納するbyte型配列を宣言
		byte[] result;
		
		// short型の変数valueに1025(=0x0401)を代入
		short value = 0x0401;

		// ビッグエンディアンで格納
		result = ByteBuffer.allocate( 2 ).order( ByteOrder.BIG_ENDIAN ).putShort( value ).array();
		System.out.println( "ビッグエンディアン" );
		System.out.println( result[ 0 ] );
		System.out.println( result[ 1 ] );
		System.out.println();

		// リトルエンディアンで格納
		result = ByteBuffer.allocate( 2 ).order( ByteOrder.LITTLE_ENDIAN ).putShort( value ).array();
		System.out.println( "リトルエンディアン" );
		System.out.println( result[ 0 ] );
		System.out.println( result[ 1 ] );
		System.out.println();

		// ビッグエンディアンで格納(格納順の指定なし)
		result = ByteBuffer.allocate( 2 ).putShort( value ).array();
		System.out.println( "ビッグエンディアン(格納順の指定なし)" );
		System.out.println( result[ 0 ] );
		System.out.println( result[ 1 ] );
		System.out.println();
	}
}

実行結果

ビッグエンディアン
4
1

リトルエンディアン
1
4

ビッグエンディアン(格納順の指定なし)
4
1

ビッグエンディアンでは最上位バイトから、リトルエンディアンでは、最下位バイトから並んでいます。

ここから、ソースコードを解説していきます。

001
import java.nio.ByteBuffer;

Javaクラスライブラリの中から「java.nio.ByteBuffer」というパッケージにあるクラスを、このプログラム内で使うために記述します。 この記述により、ByteBufferクラスが利用できるようになります。

002
import java.nio.ByteOrder;

Javaクラスライブラリの中から「java.nio.ByteOrder」というパッケージにあるクラスを、このプログラム内で使うために記述します。 この記述により、ByteOrderクラスが利用できるようになります。

004
public class Short2Bytes {

クラス名を、Short2Bytesとしています。

005
	public static void main( String[] args ) {

このmainメソッドからプログラムを実行します。

006
007
		// 結果を格納するbyte型配列を宣言
		byte[] result;

結果を格納するbyte型配列resultを宣言しています。

009
010
		// short型の変数valueに1025(=0x0401)を代入
		short value = 0x0401;

変換元の整数valueに0x401を代入しています。ここでは、byte配列に格納した結果をわかりやすくするために16進表記で代入しています。

byteの値は、16進表記の2桁ごとに区切った値になります。この場合、「0x04」と「0x01」が格納される値になります。

shrot value=1025;としても同じ結果が得られますが、byteに変換された値の確認が少し難しくなります。

例えば、value=623とした場合、byte配列には「2」と「111」が格納されます。これを16進表記にすると「0x02」と「0x6f」です。

623を代入する式をvalue=0x026fにすれば、「0x02」と「0x6f」がどのように配列に入ったかの確認が容易になります。このソースでは、結果を10進数で表示しているので出力された結果を16進数に変換して確認する必要があります。

このソースで代入しているvalueの値は0x0401なので、2桁で区切った16進数の「0x04」と「0x01」、結果として出力された10進数の「4」と「1」が同じなので直接確認することができます。

次に紹介するソースでは、出力結果を16進表記にしているので直接確認できるようになっています。

012
013
		// ビッグエンディアンで格納
		result = ByteBuffer.allocate( 2 ).order( ByteOrder.BIG_ENDIAN ).putShort( value ).array();

変数valueの値を、byte型配列resultに格納しています。格納する順序は、ビッグエンディアンです。

ByteBufferクラスのallocateメソッドで、2バイトの新しい領域を確保しています。

次に、orderメソッドByteOrder.BIG_ENDIANを渡しています。これで、格納する並び順がビッグエンディアンになります。

putShortメソッドで、変数valueの値をallocateメソッドで確保した領域に書き込みます。

最後に、arrayメソッドで、領域の値をbyte配列resultに格納します。

014
015
016
017
		System.out.println( "ビッグエンディアン" );
		System.out.println( result[ 0 ] );
		System.out.println( result[ 1 ] );
		System.out.println();

byte配列resultの値を、コンソール出力しています。resultの値は10進表記で出力されます。

019
020
		// リトルエンディアンで格納
		result = ByteBuffer.allocate( 2 ).order( ByteOrder.LITTLE_ENDIAN ).putShort( value ).array();

変数valueの値を、byte型配列resultに格納しています。格納する順序は、リトルエンディアンです。

ByteBufferクラスのallocateメソッドで、2バイトの新しい領域を確保しています。

次に、orderメソッドByteOrder.LITTLE_ENDIANを渡しています。これで、格納する並び順がリトルエンディアンになります。

putShortメソッドで、変数valueの値をallocateメソッドで確保した領域に書き込みます。

最後に、arrayメソッドで、領域の値をbyte配列resultに格納します。

021
022
023
024
		System.out.println( "リトルエンディアン" );
		System.out.println( result[ 0 ] );
		System.out.println( result[ 1 ] );
		System.out.println();

byte配列resultの値を、コンソール出力しています。resultの値は10進表記で出力されます。

026
027
		// ビッグエンディアンで格納(格納順の指定なし)
		result = ByteBuffer.allocate( 2 ).putShort( value ).array();

変数valueの値を、byte型配列resultに格納しています。格納する順序は、ビッグエンディアンです。

ByteBufferクラスのallocateメソッドで、2バイトの新しい領域を確保しています。

putShortメソッドで、変数valueの値をallocateメソッドで確保した領域に書き込みます。

最後に、arrayメソッドで、領域の値をbyte配列resultに格納します。

orderメソッドを使わない場合はビッグエンディアンになります。

028
029
030
031
		System.out.println( "ビッグエンディアン(格納順の指定なし)" );
		System.out.println( result[ 0 ] );
		System.out.println( result[ 1 ] );
		System.out.println();

byte配列resultの値を、コンソール出力しています。resultの値は10進表記で出力されます。

エンディアン確認用のJavaソースコード その2

整数0x0a0bを2バイト整数であるshort型変数に代入し、その値をbyte型配列に格納するソースコードです。

配列に格納した値は、16進数でコンソール出力しています。

Short2Bytes2.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class Short2Bytes2 {
	public static void main( String[] args ) {
		// 結果を格納するbyte型配列を宣言
		byte[] result;
		
		// short型の変数valueに0x0a0bを代入
		short value = 0x0a0b;

		// ビッグエンディアンで格納
		result = ByteBuffer.allocate( 2 ).order( ByteOrder.BIG_ENDIAN ).putShort( value ).array();
		System.out.println( "ビッグエンディアン" );
		System.out.println( String.format( "%02x", result[ 0 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 1 ] ) );	// 16進表記
		System.out.println();

		// リトルエンディアンで格納
		result = ByteBuffer.allocate( 2 ).order( ByteOrder.LITTLE_ENDIAN ).putShort( value ).array();
		System.out.println( "リトルエンディアン" );
		System.out.println( String.format( "%02x", result[ 0 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 1 ] ) );	// 16進表記
		System.out.println();
	}
}

実行結果

ビッグエンディアン
0a
0b

リトルエンディアン
0b
0a

ビッグエンディアンでは最上位バイトから、リトルエンディアンでは、最下位バイトから並んでいます。

また、結果は16進数で出力されています。

ここから、ソースコードを解説していきます。

Short2Bytes.javaとの大きな違いは、出力する値を16進数にしているところなので、その出力についてだけ解説します。

015
016
		System.out.println( String.format( "%02x", result[ 0 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 1 ] ) );	// 16進表記

結果のbyte型配列resultの値を、String.formatメソッドで16進数表現の文字列に変換しています。

System.out.println( String.format( "%02x", result[ 0 ] ) );"%02x"は、"0"埋め2桁の16進数に変換するという意味です。

これで、2桁の16進数が出力されます。

エンディアン確認用のJavaソースコード その3

整数0xabcd1234を4バイト整数であるint型変数に代入し、その値をbyte型配列に格納するソースコードです。

配列に格納した値は、16進数でコンソール出力しています。

Int2Bytes2.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class Int2Bytes2 {
	public static void main( String[] args ) {
		// 結果を格納するbyte型配列を宣言
		byte[] result;
		
		// int型の変数valueに0xabcd1234を代入
		int value = 0xabcd1234;

		// ビッグエンディアンで格納
		result = ByteBuffer.allocate( 4 ).order( ByteOrder.BIG_ENDIAN ).putInt( value ).array();
		System.out.println( "ビッグエンディアン" );
		System.out.println( String.format( "%02x", result[ 0 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 1 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 2 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 3 ] ) );	// 16進表記
		System.out.println();

		// リトルエンディアンで格納
		result = ByteBuffer.allocate( 4 ).order( ByteOrder.LITTLE_ENDIAN ).putInt( value ).array();
		System.out.println( "リトルエンディアン" );
		System.out.println( String.format( "%02x", result[ 0 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 1 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 2 ] ) );	// 16進表記
		System.out.println( String.format( "%02x", result[ 3 ] ) );	// 16進表記
		System.out.println();
	}
}

実行結果

ビッグエンディアン
ab
cd
12
34

リトルエンディアン
34
12
cd
ab

ビッグエンディアンでは最上位バイトから、リトルエンディアンでは、最下位バイトから並んでいます。

また、結果は16進数で出力されています。

ここから、ソースコードを解説していきます。

ここでは、4バイト整数byte型配列に格納する方法について説明します。

012
013
		// ビッグエンディアンで格納
		result = ByteBuffer.allocate( 4 ).order( ByteOrder.BIG_ENDIAN ).putInt( value ).array();

変数valueの値を、byte型配列resultに格納しています。格納する順序は、ビッグエンディアンです。

ByteBufferクラスのallocateメソッドで、4バイトの新しい領域を確保しています。

putIntメソッドで、変数valueの値をallocateメソッドで確保した領域に書き込みます。

最後に、arrayメソッドで、領域の値をbyte配列resultに格納します。

orderメソッドで、順序を指定しない場合はビッグエンディアンになります。

次に読んでほしいコンテンツ

"-128~127"の範囲の値を持もつことができるbyte型の値を、符号無しのint型の値にする方法は?

2019.07.09

同じ型の変数(データ)を複数個まとめて管理するデータの持ちかたがあります。これが配列です。くわしくは、記事をご覧ください。

2016.01.14

「0」と「1」の2つの数字で表される2進数(バイナリ)。一般に使われている10進数に変換するには。

2016.02.16

広告