Dart TypedData dan representasi endian besar / kecil
Jika saya menjalankan kode berikut:
Uint8List bytes = Uint8List.fromList([1, 0, 0, 128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);
Saya mendapatkan hasil sebagai berikut:
[1, 32768]
Sejak nilai aslinya
00000001 00000000 00000000 10000000
1 0 0 128
Saya berharap mereka digabungkan seperti ini:
0000000100000000 0000000010000000
256 128
Sebagai gantinya, saya mendapatkan ini:
0000000000000001 1000000000000000
1 32768
Itu little endian, bukan? Saya menjalankan kode ini di Mac saya. Apakah alasan saya mendapatkan hasil di atas karena Mac saya menggunakan little endian? Jika saya menjalankan kode yang sama pada komputer big endian, apakah akan memberikan hasil yang berbeda? (Saya mendapatkan hasil yang sama di DartPad, tetapi saya tidak tahu mesin apa yang menjalankan DartPad.)
Jawaban
Ya, diharapkan bisa memberikan hasil yang berbeda. Anda akan mendapatkan hasil yang diharapkan pada sistem big endian. Metode Anda saat ini untuk melihat data byte Anda menggunakan endianness dari sistem host. Ini termasuk DartPad karena kode yang berjalan di DartPad sedang dikompilasi ke JS, yang masih berjalan di sistem endian kecil yang sama.
Tidak ada batasan pasti untuk bahasa Dart. Namun, beberapa metode melihat data byte secara eksplisit menetapkan endianness seperti ByteData
kelas.
Berikut adalah beberapa informasi tambahan untuk jawaban Christopher Moore.
Anda dapat memeriksa ketahanan komputer Anda dengan yang berikut ini:
print(Endian.host == Endian.little);
Kebanyakan komputer pribadi menggunakan arsitektur little endian sehingga biasanya akan kembali true
.
Anda dapat menentukan endian yang ingin Anda gunakan untuk melihat data dengan menggunakan ByteData
alih-alih 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'));
}
Hasilnya adalah:
0000000100000000 0000000010000000
Jika Anda mengubah Endian.big
ke Endian.little
hasilnya akan:
0000000000000001 1000000000000000
Anda dapat membaca lebih lanjut tentang ini di sini:
- Bekerja dengan byte di Dart