当 int 通常是 32 位或 64 位时,"int" 如何表示一个字节(8 位)?
How does an "int" represent a byte (8 bits) when an int is normally 32 or 64 bits?
我很好奇在 Dart 编程语言中一个字节是如何用 int
类型表示的。我很困惑,因为在 Dart 非常相似的 Java 中,int
是 32 位。
我问是因为领先的 flutter ble 库 Flutter Blue 在处理 ble 字节时似乎可以处理 List<int>
。
但是根据官方文档:
https://flutter.dev/docs/development/platform-integration/platform-channels#codec
使用了 Uint8List - 这就是 byte[] 等价物的意义所在。
那些无符号的 8 位整数似乎只是从 Uint8List
-> List<int>
转换为 32 位有符号整数?即十进制 2 然后从 00000010
转换为 00000000000000000000000000000010
?
如果要写入字节流,这似乎会产生影响。需要将 int
转换为 Uint8
。
dart 中 int
的大小对于局部变量来说并不是完全可预测的,正如 Irn 提到的 。如果认为可能的话,int
的大小可能会减少作为优化。
如果您进行从 Uint8List
到 List<int>
的显式转换以创建新的 List
对象,则新对象将具有更大尺寸的 int
个元素超过 8 位。可能是 32 位,可能是 64 位,也可能更少。编译器将根据它所看到的进行选择。根据int
class,默认是一个带符号的64位整数。
如果您尝试从 int
到 Uint8List
,每个 int
将被截断为 8 位。
首先,让我们弄清楚一件事。 int
不是固有的 32 位或普遍的 64 位。这只是通用语言制定的约定,包括 Java。例如,在 C 中,int
的大小是一个实现细节,它取决于编译器、体系结构和内存地址的大小,因此它可以是 8、16、32 或 64 位(或在更深奥的平台上,完全不同的东西,比如 24 位)。因此,认为 Dart 没有 int
是 32 位整数类型是在做一些“错误”的事情的想法有点荒谬。
现在,Dart 中的 int
不是固定数据类型。与 C 一样,它取决于 运行 所在的平台。
- 移动设备:
int
是一个 64 位整数
- Web:
int
映射到 JavaScript Number
这是一个 64 位浮点数(即 double
)
- 其他:
int
可以定义为实现细节
就是这样。 Dart 没有任何其他整数类型的概念。 (即没有像 byte、short、char、long、long long 等基本类型。)
您在 Uint8List
中看到的是对 64 位整数列表的抽象,使其看起来像字节列表。我不确定它在内部是如何表示的(每个“字节”都是它自己的 int
,使用 bit-flags 在单个 int
中存储 8 个字节的信息,或者它是一个本机实现完全在做其他事情),但归根结底,这并不重要。
Uint8List
派生自 List<int>
;在预期 List<int>
的地方传递 Uint8List
不会更改数据的表示形式。
当您从 Uint8List
(例如 operator []
)阅读 单个 int
时,您将获得一份八位字节扩展为 int
是什么。
当您 将 一个 int
写入 Uint8List
时(例如使用 operator []=
),存储的值将被截断以仅包含低 8 位。
关于如何使用 int
来表示字节不应该有任何混淆,因为它都归结为位以及您如何存储和操作它们。
为了简单起见,让我们假设 int
比一个字节大——一个 int 是 32 位,一个 byte 是 8 位。因为,此时我们只处理位,您可以看到 int 可能包含 4 个字节,因为 32/8 是 4,即我们可以使用 int 来存储字节而不会丢失信息。
It seems as those the unsigned 8 bit integers are just then converted to a 32 bit signed int going from Uint8List -> List ? i.e. decimal 2 is is then converted from 00000010 to 00000000000000000000000000000010?
你可以那样做,但我之前说过,你可以在一个 int 中存储多个字节。
考虑一下,如果您有字符串 Hello, World!
,它最多为 13 个字节,并且您想将这些字节存储在 int
的列表中,假设每个 int
是 32位;我们只需要用4个int来表示这个字符串,因为13 * 8
是104位,4个32位的int可以容纳128位的信息。
It seems this has ramifications if one would like to write a byte stream. Would need to cast the int's to Uint8's.
不一定。
由字节 'H', 'e', 'l', 'l', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'
组成的字节流可以写入称为 Bit Array
的数据结构。上述流的位数组如下所示:
[01001000011001010110110001101100011011110010110000100000010101110110111101110010011011000110010000100001]
或 32 位整数列表:
[1214606444,1865162839,1869769828,33]
如果我们想将这个整数列表转换回字节,我们只需要读取 8 位块中的数据以检索原始字节。我将用这个简单编写的 dart 程序来演示它:
String readInts(List<int> bitArray) {
final buffer = StringBuffer();
for (var chunk in bitArray) {
for (var offset = 24; offset >= 0; offset -= 8) {
if (chunk < 1 << offset) {
continue;
}
buffer.writeCharCode((chunk >> offset) & 0xff);
}
}
return buffer.toString();
}
void main() {
print(readInts([1214606444,1865162839,1869769828,33]));
}
可以按照相同的过程将字节转换为整数 - 您只需将每 4 个字节组合起来形成一个 32 位整数。
输出
Hello, World!
当然,您不需要自己编写这样的代码,因为 dart 已经在 Uint8List
class
Dart int
类型是一个 64 位二进制补码数——除了为 web 编译时,它是一个没有小数部分的 64 位浮点数(JavaScript 数字它有一个整数值)。
如何在内部表示这些值取决于优化,如果运行时系统确定该值适合,则可以将它们表示为更小的值。那是一个优化,你将无法区分。
“字节”值是 0..255 范围内的整数。您显然可以将字节值存储在 int
.
中
存储多个字节的最有效方法是 Uint8List
,它实现了 List<int>
。它将每个元素存储为一个八位字节。
当您从 Unit8List
中读取一个值时,其字节值由 int
表示。当您在 Uint8List
中存储 int
时,仅存储低 8 位。
因此它确实扩展读取和截断写入以在八位字节和 64 位值之间移动值。
我很好奇在 Dart 编程语言中一个字节是如何用 int
类型表示的。我很困惑,因为在 Dart 非常相似的 Java 中,int
是 32 位。
我问是因为领先的 flutter ble 库 Flutter Blue 在处理 ble 字节时似乎可以处理 List<int>
。
但是根据官方文档: https://flutter.dev/docs/development/platform-integration/platform-channels#codec 使用了 Uint8List - 这就是 byte[] 等价物的意义所在。
那些无符号的 8 位整数似乎只是从 Uint8List
-> List<int>
转换为 32 位有符号整数?即十进制 2 然后从 00000010
转换为 00000000000000000000000000000010
?
如果要写入字节流,这似乎会产生影响。需要将 int
转换为 Uint8
。
dart 中 int
的大小对于局部变量来说并不是完全可预测的,正如 Irn 提到的 int
的大小可能会减少作为优化。
如果您进行从 Uint8List
到 List<int>
的显式转换以创建新的 List
对象,则新对象将具有更大尺寸的 int
个元素超过 8 位。可能是 32 位,可能是 64 位,也可能更少。编译器将根据它所看到的进行选择。根据int
class,默认是一个带符号的64位整数。
如果您尝试从 int
到 Uint8List
,每个 int
将被截断为 8 位。
首先,让我们弄清楚一件事。 int
不是固有的 32 位或普遍的 64 位。这只是通用语言制定的约定,包括 Java。例如,在 C 中,int
的大小是一个实现细节,它取决于编译器、体系结构和内存地址的大小,因此它可以是 8、16、32 或 64 位(或在更深奥的平台上,完全不同的东西,比如 24 位)。因此,认为 Dart 没有 int
是 32 位整数类型是在做一些“错误”的事情的想法有点荒谬。
现在,Dart 中的 int
不是固定数据类型。与 C 一样,它取决于 运行 所在的平台。
- 移动设备:
int
是一个 64 位整数 - Web:
int
映射到 JavaScriptNumber
这是一个 64 位浮点数(即double
) - 其他:
int
可以定义为实现细节
就是这样。 Dart 没有任何其他整数类型的概念。 (即没有像 byte、short、char、long、long long 等基本类型。)
您在 Uint8List
中看到的是对 64 位整数列表的抽象,使其看起来像字节列表。我不确定它在内部是如何表示的(每个“字节”都是它自己的 int
,使用 bit-flags 在单个 int
中存储 8 个字节的信息,或者它是一个本机实现完全在做其他事情),但归根结底,这并不重要。
Uint8List
派生自 List<int>
;在预期 List<int>
的地方传递 Uint8List
不会更改数据的表示形式。
当您从 Uint8List
(例如 operator []
)阅读 单个 int
时,您将获得一份八位字节扩展为 int
是什么。
当您 将 一个 int
写入 Uint8List
时(例如使用 operator []=
),存储的值将被截断以仅包含低 8 位。
关于如何使用 int
来表示字节不应该有任何混淆,因为它都归结为位以及您如何存储和操作它们。
为了简单起见,让我们假设 int
比一个字节大——一个 int 是 32 位,一个 byte 是 8 位。因为,此时我们只处理位,您可以看到 int 可能包含 4 个字节,因为 32/8 是 4,即我们可以使用 int 来存储字节而不会丢失信息。
It seems as those the unsigned 8 bit integers are just then converted to a 32 bit signed int going from Uint8List -> List ? i.e. decimal 2 is is then converted from 00000010 to 00000000000000000000000000000010?
你可以那样做,但我之前说过,你可以在一个 int 中存储多个字节。
考虑一下,如果您有字符串 Hello, World!
,它最多为 13 个字节,并且您想将这些字节存储在 int
的列表中,假设每个 int
是 32位;我们只需要用4个int来表示这个字符串,因为13 * 8
是104位,4个32位的int可以容纳128位的信息。
It seems this has ramifications if one would like to write a byte stream. Would need to cast the int's to Uint8's.
不一定。
由字节 'H', 'e', 'l', 'l', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'
组成的字节流可以写入称为 Bit Array
的数据结构。上述流的位数组如下所示:
[01001000011001010110110001101100011011110010110000100000010101110110111101110010011011000110010000100001]
或 32 位整数列表:
[1214606444,1865162839,1869769828,33]
如果我们想将这个整数列表转换回字节,我们只需要读取 8 位块中的数据以检索原始字节。我将用这个简单编写的 dart 程序来演示它:
String readInts(List<int> bitArray) {
final buffer = StringBuffer();
for (var chunk in bitArray) {
for (var offset = 24; offset >= 0; offset -= 8) {
if (chunk < 1 << offset) {
continue;
}
buffer.writeCharCode((chunk >> offset) & 0xff);
}
}
return buffer.toString();
}
void main() {
print(readInts([1214606444,1865162839,1869769828,33]));
}
可以按照相同的过程将字节转换为整数 - 您只需将每 4 个字节组合起来形成一个 32 位整数。
输出
Hello, World!
当然,您不需要自己编写这样的代码,因为 dart 已经在 Uint8List
class
Dart int
类型是一个 64 位二进制补码数——除了为 web 编译时,它是一个没有小数部分的 64 位浮点数(JavaScript 数字它有一个整数值)。
如何在内部表示这些值取决于优化,如果运行时系统确定该值适合,则可以将它们表示为更小的值。那是一个优化,你将无法区分。
“字节”值是 0..255 范围内的整数。您显然可以将字节值存储在 int
.
存储多个字节的最有效方法是 Uint8List
,它实现了 List<int>
。它将每个元素存储为一个八位字节。
当您从 Unit8List
中读取一个值时,其字节值由 int
表示。当您在 Uint8List
中存储 int
时,仅存储低 8 位。
因此它确实扩展读取和截断写入以在八位字节和 64 位值之间移动值。