DartTypedDataとビッグ/リトルエンディアン表現

Dec 20 2020

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

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が実行されているマシンがわかりません。)

回答

3 ChristopherMoore Dec 20 2020 at 12:03

はい、異なる結果が得られると予想されます。ビッグエンディアンシステムで期待される結果が得られます。バイトデータを表示する現在の方法は、ホストシステムのエンディアンを使用します。DartPadで実行されているコードはJSにコンパイルされているため、これにはDartPadが含まれます。JSは同じリトルエンディアンシステムで実行されています。

Dart言語には決まったエンディアンはありません。ただし、バイトデータを表示する一部のメソッドは、ByteDataクラスのようにエンディアンを明示的に設定します。

1 Suragch Dec 28 2020 at 07:10

クリストファー・ムーアの答えに対するいくつかの追加情報があります。

次の方法で、コンピュータのエンディアンを確認できます。

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でバイトを操作する