如何解决当int通常为32或64位时,“ int”如何表示一个字节8位? 输出
我很好奇在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
类型是64位二进制补码-除非是为网络编译的,否则它是没有小数部分的64位浮点数(具有整数值的JavaScript数字)
这些值在内部的表示方式取决于优化,如果运行时系统确定该值适合,则可以将它们表示为较小的值。这是一种优化,您将无法分辨出差异。
“字节”值是0..255范围内的整数。您显然可以将字节值存储在int
中。
存储多个字节的最有效方法是Uint8List
,它实现了List<int>
。它将每个元素存储为一个八位字节。
当您从Unit8List
中读取值时,其字节值由int
表示。当您将int
存储在Uint8List
中时,仅存储低8位。
因此,它确实会扩展读取和截断写入以在八位字节和64位值之间移动值。
正如Irn提到的here那样,对于局部变量来说,int
的大小并不是完全可预测的。如果可以考虑的话,可以将int
的大小作为一种优化来减小。
如果您从Uint8List
到List<int>
进行显式转换以创建新的List
对象,则新对象将包含int
个元素,其大小大于8位。可能是32位,也许是64位,也许更少。编译器将根据看到的内容进行选择。根据{{3}},默认值为带符号的64位整数。
如果您尝试从int
到Uint8List
,则每个int
将被截断为8位。
首先,让我们澄清一件事。 int
本质上不是通用的32位或64位。那只是包括Java在内的通用语言制定的约定。例如,在C语言中,int
的大小是一个实现细节,它取决于编译器,体系结构和内存地址的大小,因此它可以是8位,16位,32位或64位(或在更深奥的平台上,完全是其他东西,例如24位)。因此,认为Dart通过使int
不是32位整数类型来做“错误的事情”的想法有点荒谬。
现在,Dart中的int
并不是固定的数据类型。像C一样,它取决于它所运行的平台。
- 移动设备:
int
是64位整数 - 网络:
int
映射到JavaScriptNumber
,它是64位浮点数(即double
) - 其他:
int
可以定义为实施细节
就是这样。 Dart没有任何其他整数类型的概念。 (即,没有像原始类型这样的东西,如byte,short,char,long,long long等。)
在Uint8List
中看到的是对64位整数列表的抽象,使其看起来像字节列表。我不确定如何在内部表示(每个“字节”都是自己的int
,使用位标志在单个int
中存储8个字节的信息,或者它是本机实现)完全是在做其他事情),但最终这并不重要。
Uint8List
源自List<int>
;在期望Uint8List
的地方传递List<int>
不会改变数据的表示形式。
当您从int
(例如,使用Uint8List
)读取单个operator []
时,您将得到一个八位字节的副本,该副本扩展为{ {1}}是。
当您将int
写成int
时(例如,使用Uint8List
),存储的值将被截断以仅包含低8位
对于如何使用int
表示字节,应该没有任何困惑,因为它全都归结为位以及如何存储和操作它们。
为简单起见,让我们假设int
大于字节-一个int为32位,一个字节为8位。由于此时我们仅处理位,因此您可以看到int可能包含4个字节,因为32/8为4,即我们可以使用int来存储字节而不会丢失信息。
似乎那些无符号的8位整数刚刚被转换为Uint8List-> List中的32位带符号的int?即小数点2是否从00000010转换为00000000000000000000000000000010 ??
您可以这样做,但是根据我之前所说,您可以在一个int中存储多个字节。
考虑一下,如果您有字符串Hello,World!
,该字符串最多13个字节,并且您想将这些字节存储在int
的列表中,假设每个int
为32位;我们只需要使用4个整数来表示此字符串,因为13 * 8
是104位,而四个32位整数可以容纳128位信息。
如果要写一个字节流,这似乎有影响。需要将int转换为Uint8。
不一定。
由字节'H','e','l',',' ','W','o','r','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,33]));
}
可以遵循相同的过程将字节转换为整数-您只需将每4个字节合并即可形成一个32位整数。
输出
Hello,World!
当然,您不需要自己编写这样的代码,因为dart已经在Uint8List
类中为您完成了此任务
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。