Dart TypedData i reprezentacja dużego / małego endianu
Jeśli uruchomię następujący kod:
Uint8List bytes = Uint8List.fromList([1, 0, 0, 128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);
Otrzymuję następujący wynik:
[1, 32768]
Ponieważ oryginalne wartości były
00000001 00000000 00000000 10000000
1 0 0 128
Spodziewałbym się, że zostaną połączone w ten sposób:
0000000100000000 0000000010000000
256 128
Zamiast tego dostałem to:
0000000000000001 1000000000000000
1 32768
To trochę endian, prawda? Uruchamiam ten kod na moim Macu. Czy jest to powód, dla którego otrzymałem powyższy wynik, ponieważ mój Mac używa Little Endian? Gdybym uruchomił ten sam kod na komputerze typu big endian, czy dałoby to inny wynik? (Otrzymuję ten sam wynik na DartPadzie, ale nie wiem, na jakiej maszynie działa DartPad).
Odpowiedzi
Tak, można by oczekiwać, że da inny wynik. Otrzymasz oczekiwany wynik w systemie big endian. Twoja obecna metoda przeglądania danych bajtowych wykorzystuje endianness systemu hosta. Obejmuje to DartPad, ponieważ kod działający w DartPad jest kompilowany do JS, który nadal działa w tym samym systemie little endian.
Nie ma określonego endianness dla języka Dart. Jednak niektóre metody przeglądania danych bajtowych jawnie ustawiają endianness, podobnie jak ByteData
klasa.
Oto dodatkowe informacje dotyczące odpowiedzi Christophera Moore'a.
Możesz sprawdzić endianness swojego komputera, wykonując następujące czynności:
print(Endian.host == Endian.little);
Większość komputerów osobistych wykorzystuje architekturę little endian, więc ta zwykle powróci true
.
Możesz określić endianness, z jakim chcesz przeglądać dane, używając ByteData
zamiast 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'));
}
Wynik to:
0000000100000000 0000000010000000
Jeśli zmieni Endian.big
się Endian.little
wynik będzie:
0000000000000001 1000000000000000
Możesz przeczytać więcej na ten temat tutaj:
- Praca z bajtami w Dart