DartTypedDataとビッグ/リトルエンディアン表現
次のコードを実行すると、次のようになります。
Uint8List bytes = Uint8List.fromList([1, 0, 0, 128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);
次の結果が得られます。
[1, 32768]
元の値が
00000001 00000000 00000000 10000000
1 0 0 128
私はそれらが次のように組み合わされることを期待していました:
0000000100000000 0000000010000000
256 128
代わりに、私はこれを手に入れました:
0000000000000001 1000000000000000
1 32768
それはリトルエンディアンですよね?このコードをMacで実行しています。Macがリトルエンディアンを使用しているために上記の結果が得られた理由は何ですか?ビッグエンディアンのコンピューターで同じコードを実行した場合、異なる結果が得られますか?(DartPadでも同じ結果が得られますが、DartPadが実行されているマシンがわかりません。)
回答
はい、異なる結果が得られると予想されます。ビッグエンディアンシステムで期待される結果が得られます。バイトデータを表示する現在の方法は、ホストシステムのエンディアンを使用します。DartPadで実行されているコードはJSにコンパイルされているため、これにはDartPadが含まれます。JSは同じリトルエンディアンシステムで実行されています。
Dart言語には決まったエンディアンはありません。ただし、バイトデータを表示する一部のメソッドは、ByteData
クラスのようにエンディアンを明示的に設定します。
クリストファー・ムーアの答えに対するいくつかの追加情報があります。
次の方法で、コンピュータのエンディアンを確認できます。
print(Endian.host == Endian.little);
ほとんどのパーソナルコンピュータはリトルエンディアンアーキテクチャを使用しているため、通常はに戻りtrue
ます。
次のByteData
代わりにを使用して、データを表示するエンディアンを指定できますBytesBuffer
。
import 'dart:typed_data';
void main() {
Uint8List byteList = Uint8List.fromList([1, 0, 0, 128]);
ByteData byteData = ByteData.sublistView(byteList);
int value = byteData.getUint16(0, Endian.big);
print(value.toRadixString(2).padLeft(16, '0'));
value = byteData.getUint16(2, Endian.big);
print(value.toRadixString(2).padLeft(16, '0'));
}
結果は次のとおりです。
0000000100000000 0000000010000000
結果に変更Endian.big
するとEndian.little
、次のようになります。
0000000000000001 1000000000000000
あなたはここでこれについてもっと読むことができます:
- Dartでバイトを操作する