Dart TypedData und Big / Little Endian-Darstellung

Dec 20 2020

Wenn ich den folgenden Code ausführe:

Uint8List bytes = Uint8List.fromList([1, 0, 0, 128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);

Ich erhalte folgendes Ergebnis:

[1, 32768]

Da waren die ursprünglichen Werte

00000001 00000000 00000000 10000000
1        0        0        128

Ich hätte erwartet, dass sie so kombiniert werden:

0000000100000000 0000000010000000
256              128

Stattdessen habe ich folgendes bekommen:

0000000000000001 1000000000000000
1                32768

Das ist Little Endian, oder? Ich führe diesen Code auf meinem Mac aus. Ist der Grund, warum ich das obige Ergebnis erhalten habe, weil mein Mac Little Endian verwendet? Wenn ich denselben Code auf einem Big-Endian-Computer ausführen würde, würde dies zu einem anderen Ergebnis führen? (Ich erhalte das gleiche Ergebnis auf DartPad, weiß aber nicht, auf welchem ​​Computer DartPad ausgeführt wird.)

Antworten

3 ChristopherMoore Dec 20 2020 at 12:03

Ja, es wird erwartet, dass es zu einem anderen Ergebnis kommt. Sie würden Ihr erwartetes Ergebnis auf einem Big-Endian-System erhalten. Ihre aktuelle Methode zum Anzeigen Ihrer Byte-Daten verwendet die Endianität des Host-Systems. Dies schließt DartPad ein, da der in DartPad ausgeführte Code zu JS kompiliert wird, das immer noch auf demselben kleinen Endian-System ausgeführt wird.

Es gibt keine festgelegte Endianness für die Dart-Sprache. Einige Methoden zum Anzeigen von Byte-Daten legen jedoch explizit eine Endianness wie die ByteDataKlasse fest.

1 Suragch Dec 28 2020 at 07:10

Hier sind einige zusätzliche Informationen zu Christopher Moores Antwort.

Sie können die Endianness Ihres Computers folgendermaßen überprüfen:

print(Endian.host == Endian.little);

Die meisten PCs verwenden eine Little-Endian-Architektur, sodass diese normalerweise zurückkehren true.

Sie können die Endianität angeben, mit der Sie die Daten anzeigen möchten, indem Sie ByteDataanstelle von 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'));
}

Das Ergebnis ist:

0000000100000000 0000000010000000

Wenn Sie Endian.bigzum Endian.littleErgebnis wechseln , werden:

0000000000000001 1000000000000000

Mehr dazu lesen Sie hier:

  • Arbeiten mit Bytes in Dart