Dart TypedData y representación de endian grande / pequeño
Si ejecuto el siguiente código:
Uint8List bytes = Uint8List.fromList([1, 0, 0, 128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);
Obtengo el siguiente resultado:
[1, 32768]
Dado que los valores originales eran
00000001 00000000 00000000 10000000
1 0 0 128
Hubiera esperado que se combinaran así:
0000000100000000 0000000010000000
256 128
En cambio, obtuve esto:
0000000000000001 1000000000000000
1 32768
Eso es pequeño endian, ¿verdad? Estoy ejecutando este código en mi Mac. ¿La razón por la que obtuve el resultado anterior es porque mi Mac usa little endian? Si ejecuto el mismo código en una computadora Big Endian, ¿daría un resultado diferente? (Obtengo el mismo resultado en DartPad, pero no sé en qué máquina se está ejecutando DartPad).
Respuestas
Sí, se esperaría que diera un resultado diferente. Obtendría el resultado esperado en un sistema big endian. Su método actual de ver sus datos de bytes utiliza el endianness del sistema host. Esto incluye DartPad ya que el código que se ejecuta en DartPad se está compilando en JS, que todavía se ejecuta en ese mismo sistema little endian.
No hay un endianness establecido para el lenguaje Dart. Sin embargo, algunos métodos de visualización de datos de bytes establecen explícitamente un endianness como la ByteData
clase.
Aquí hay información adicional a la respuesta de Christopher Moore.
Puede verificar la endianidad de su computadora con lo siguiente:
print(Endian.host == Endian.little);
La mayoría de las computadoras personales usan una arquitectura little endian, por lo que generalmente regresará true
.
Puede especificar el endianness con el que desea ver los datos utilizando en ByteData
lugar 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'));
}
El resultado es:
0000000100000000 0000000010000000
Si cambia Endian.big
al Endian.little
resultado será:
0000000000000001 1000000000000000
Puedes leer más sobre esto aquí:
- Trabajando con bytes en Dart