Dart TypedData et représentation big / little endian

Dec 20 2020

Si j'exécute le code suivant:

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

J'obtiens le résultat suivant:

[1, 32768]

Puisque les valeurs d'origine étaient

00000001 00000000 00000000 10000000
1        0        0        128

Je me serais attendu à ce qu'ils soient combinés comme ceci:

0000000100000000 0000000010000000
256              128

Au lieu de cela, j'ai obtenu ceci:

0000000000000001 1000000000000000
1                32768

C'est le petit boutiste, non? J'exécute ce code sur mon Mac. Est-ce que la raison pour laquelle j'ai obtenu le résultat ci-dessus est que mon Mac utilise Little Endian? Si j'exécutais le même code sur un ordinateur big endian, cela donnerait-il un résultat différent? (J'obtiens le même résultat sur DartPad, mais je ne sais pas sur quelle machine DartPad fonctionne.)

Réponses

3 ChristopherMoore Dec 20 2020 at 12:03

Oui, on s'attend à ce qu'il donne un résultat différent. Vous obtiendrez le résultat attendu sur un système big endian. Votre méthode actuelle de visualisation de vos données d'octets utilise l'endianness du système hôte. Cela inclut DartPad puisque le code exécuté dans DartPad est en cours de compilation vers JS, qui est toujours en cours d'exécution sur ce même petit système endian.

Il n'y a pas d'endianité définie pour le langage Dart. Cependant, certaines méthodes d'affichage des données d'octets définissent explicitement une endianité comme la ByteDataclasse.

1 Suragch Dec 28 2020 at 07:10

Voici quelques informations supplémentaires à la réponse de Christopher Moore.

Vous pouvez vérifier l'endianness de votre ordinateur avec les éléments suivants:

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

La plupart des ordinateurs personnels utilisent une architecture little endian, ce qui revient généralement true.

Vous pouvez spécifier l'endianness avec laquelle vous souhaitez afficher les données en utilisant ByteDataau lieu de 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'));
}

Le résultat est:

0000000100000000 0000000010000000

Si vous changez Endian.bigde Endian.littlerésultat sera:

0000000000000001 1000000000000000

Vous pouvez en savoir plus ici:

  • Travailler avec des octets dans Dart