Dart TypedData ve büyük / küçük endian gösterimi

Dec 20 2020

Aşağıdaki kodu çalıştırırsam:

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

Şu sonucu alıyorum:

[1, 32768]

Orijinal değerler olduğundan

00000001 00000000 00000000 10000000
1        0        0        128

Onların şu şekilde birleşmesini beklerdim:

0000000100000000 0000000010000000
256              128

Bunun yerine şunu anladım:

0000000000000001 1000000000000000
1                32768

Bu küçük endian, değil mi? Bu kodu Mac'imde çalıştırıyorum. Mac'imin küçük endian kullanması nedeniyle yukarıdaki sonucu almamın nedeni bu mu? Aynı kodu büyük bir endian bilgisayarda çalıştırsaydım, farklı bir sonuç verir miydi? (DartPad'de de aynı sonucu alıyorum, ancak DartPad'in hangi makinede çalıştığını bilmiyorum.)

Yanıtlar

3 ChristopherMoore Dec 20 2020 at 12:03

Evet farklı bir sonuç vermesi beklenirdi. Beklediğiniz sonucu büyük bir endian sisteminde alırsınız. Bayt verilerinizi görüntülemek için geçerli yönteminiz, ana bilgisayar sisteminin dayanıklılığını kullanır. Bu, DartPad'de çalışan kod hala aynı küçük endian sisteminde çalışan JS'ye derlendiğinden DartPad'i içerir.

Dart dili için belirlenmiş bir süre yoktur. Bununla birlikte, bayt verilerini görüntülemenin bazı yöntemleri, ByteDatasınıf gibi açık bir şekilde bir sonluluk belirler .

1 Suragch Dec 28 2020 at 07:10

Christopher Moore'un cevabına bazı ek bilgiler burada.

Aşağıdakilerle bilgisayarınızın dayanıklılığını kontrol edebilirsiniz:

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

Çoğu kişisel bilgisayar, küçük endian mimarisini kullanır, bu yüzden genellikle geri döner true.

Verileri görüntülemek istediğiniz süreyi ByteDatabunun yerine şunu kullanarak belirtebilirsiniz 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'));
}

Sonuç:

0000000100000000 0000000010000000

Eğer değiştirirseniz Endian.bigiçin Endian.littlesonuç olacaktır:

0000000000000001 1000000000000000

Bununla ilgili daha fazla bilgiyi buradan okuyabilirsiniz:

  • Dart'ta baytlarla çalışma