MENU

ArrayBuffer

【JavaScript】 TypedArrayのエンディアンを確認する方法

更新日:2021/07/06

JavaScriptの2バイト以上のTypedArrayオブジェクトは、エンディアンを考慮したメモリアクセスがおこなわれます。

 

しかし、この時のエンディアンが何なのでしょうか。

 

確認してみましょう。

 

TypedArrayのエンディアン

 

エンディアンは、コンピューターのメモリ上にデータを格納する際、どのような順番でバイトをセットしていくのかを表す用語です。

 

詳しくは、こちら読んでみてください。
エンディアンとは何か調べてみた

 

TypedArrayはデータアクセス時に周囲のエージェントの[[LittleEndian]]フィールドを参照して、リトルエンディアンかビッグエンディアンかを判定します。

 

[[LittleEndian]]フィールドは、次のように定義されています。

 

選択は実装依存であり、実装にとって最も効率的な代替手段でなければなりません。 いったん値が決まると、変更できません。
8.6 エージェント(Agents)

 

選択とは、リトルエンディアンにするかビッグエンディアンにするかということです。

 

そして実装依存、つまりJavaScriptエンジンを作成するエンジニアが選択できるということです。

 

ようするに、言語仕様としては、どちらか決まっていないということですね。

確認方法の概要

 

では今使っているJavaScript環境での、TypedArrayオブジェクトのエンディアンを確認してみます。

 

方法は、ArrayBufferを共有するUint8Arrayと他のTypedArrayを用意します。

 

次に他のTypedArrayに値をセットします。

 

最後に、セットした値のバイトとUint8Arrayの要素を順番に比較します。

 

一致すればビッグエンディアンで、一致しなければリトルエンディアンです。

 

入力データ01 02 03 04

 

←下位アドレスアドレス増加分上位アドレス→
+1+2+3+4
01020304
一致:ビッグエンディアン
04030201
不一致:リトルエンディアン

エンディアン確認コード

 

次のコードは、ビッグエンディアンかリトルエンディアンか、またはその他のエンディアンかを確認しています。

 

ビッグエンディアンかリトルエンディアンかを確認

 


const u32 = Uint16Array.of( 0x1122 );
const u8 = new Uint8Array( u32.buffer );

const endian = (()=>{
    if( u8[0] === 0x11 && u8[1]  === 0x22 && u8[2] === 0x33 && u8[3] === 0x44 )
        return "ビッグエンディアン";

    if( u8[3] === 0x11 && u8[2]  === 0x22 && u8[1] === 0x33 && u8[0] === 0x44 )
        return "リトルエンディアン";

    return "不明なエンディアン";
})();

console.log( endian + "です" );

 

実際には、TypedArrayへのセット時に値をバイト単位に分解して、リトルエンディアンならバイトを並び替え、バイト毎にメモリへセットしています。
データ取得時は、その逆です。

 

つまり、不明なエンディアンが検出されることがありません。

 

他のエンディアンを考慮しないなら、もっと単純です。

 

Uint16Arrayに整数1をセットして、Uint8Arrayの先頭バイトが1になればリトルエンディアンです。

 

Uint16Array: 0x0001
Uint8Array: 0x01 0x00 ← リトルエンディアン

 

これをコードにすると、次のようになります。

 

リトルエンディアンかを確認

 


const endian = new Uint8Array( Uint16Array.of( 1).buffer )[0] === 1 
        ? "リトルエンディアン" : "リトルエンディアンではない" ;

console.log( endian + "です" );

 

スポンサーリンク

記事の内容について

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

OFUSEを設置してみました。
応援いただけると嬉しいです。