Dart TypedData e representação big / little endian
Se eu executar o seguinte código:
Uint8List bytes = Uint8List.fromList([1, 0, 0, 128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);
Eu obtenho o seguinte resultado:
[1, 32768]
Uma vez que os valores originais eram
00000001 00000000 00000000 10000000
1 0 0 128
Eu esperava que eles fossem combinados assim:
0000000100000000 0000000010000000
256 128
Em vez disso, eu peguei este:
0000000000000001 1000000000000000
1 32768
Isso é pequeno endian, certo? Estou executando este código no meu Mac. A razão pela qual obtive o resultado acima é porque meu Mac usa little endian? Se eu executasse o mesmo código em um computador big endian, o resultado seria diferente? (Obtenho o mesmo resultado no DartPad, mas não sei em que máquina o DartPad está sendo executado.)
Respostas
Sim, seria esperado um resultado diferente. Você obteria o resultado esperado em um sistema big endian. Seu método atual de visualizar seus dados de byte usa o endianness do sistema host. Isso inclui o DartPad, já que o código em execução no DartPad está sendo compilado para JS, que ainda está em execução no mesmo pequeno sistema endian.
Não há endianness definido para a linguagem Dart. No entanto, alguns métodos de visualização de dados de byte definem explicitamente um endianness como a ByteData
classe.
Aqui estão algumas informações adicionais para a resposta de Christopher Moore.
Você pode verificar o endianness do seu computador com o seguinte:
print(Endian.host == Endian.little);
A maioria dos computadores pessoais usa arquitetura little endian, de modo que geralmente retorna true
.
Você pode especificar o endianness com o qual deseja visualizar os dados usando em ByteData
vez 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'));
}
O resultado é:
0000000100000000 0000000010000000
Se você mudar Endian.big
para Endian.little
o resultado será:
0000000000000001 1000000000000000
Você pode ler mais sobre isso aqui:
- Trabalhando com bytes no Dart