Dart TypedData 和大/小端表示

Sur*_*gch 4 endianness dart

如果我运行以下代码:

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

我得到以下结果:

[1, 32768]
Run Code Online (Sandbox Code Playgroud)

由于原始值为

00000001 00000000 00000000 10000000
1        0        0        128
Run Code Online (Sandbox Code Playgroud)

我本以为它们会像这样组合起来:

0000000100000000 0000000010000000
256              128
Run Code Online (Sandbox Code Playgroud)

相反,我得到了这个:

0000000000000001 1000000000000000
1                32768
Run Code Online (Sandbox Code Playgroud)

那是小端,对吧?我正在我的 Mac 上运行这段代码。我得到上述结果的原因是因为我的 Mac 使用小端吗?如果我在大端计算机上运行相同的代码,它会给出不同的结果吗?(我在 DartPad 上得到了相同的结果,但我不知道 DartPad 运行在什么机器上。)

Chr*_*ore 5

是的,预计会给出不同的结果。您将在大端系统上得到预期的结果。您当前查看字节数据的方法使用主机系统的字节顺序。这包括 DartPad,因为 DartPad 中运行的代码被编译为 JS,而 JS 仍然在相同的小端系统上运行。

Dart 语言没有固定的字节顺序。然而,一些查看字节数据的方法确实像ByteData类一样显式设置了字节序。


Sur*_*gch 5

以下是克里斯托弗·摩尔的回答的一些附加信息。

您可以使用以下命令检查计算机的字节顺序:

print(Endian.host == Endian.little);
Run Code Online (Sandbox Code Playgroud)

大多数个人计算机使用小端架构,因此通常会返回true

您可以使用而不是指定要查看数据的字节ByteData顺序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'));
}
Run Code Online (Sandbox Code Playgroud)

结果是:

0000000100000000 0000000010000000
Run Code Online (Sandbox Code Playgroud)

如果改成Endian.big这样,Endian.little结果将是:

0000000000000001 1000000000000000
Run Code Online (Sandbox Code Playgroud)

您可以在这里阅读更多相关内容: