ruby - Ruby:为什么 unpack('Q') 给出的结果与手动转换不同?
问题描述
我正在尝试编写一个函数,该函数将.unpack('Q')
(解压缩到 uint64_t)而不访问解压缩方法。
当我手动从字符串转换为二进制到 uint64 时,我得到的结果不同于.unpack('Q')
:
Integer('abcdefgh'.unpack('B*').first, 2) # => 7017280452245743464
'abcdefgh'.unpack('Q').first # => 7523094288207667809
我不明白这里发生了什么。
我也不明白为什么.unpack('Q')
不管输入的大小如何,输出都是固定的。如果我在 'abcdefgh' 之后添加一千个字符,然后 unpack('Q') 它,我仍然会得到[7523094288207667809]
?
解决方案
字节顺序很重要:
Integer('abcdefgh'.
each_char.
flat_map { |c| c.unpack('B*') }.
reverse.
join, 2)
#⇒ 7523094288207667809
'abcdefgh'.unpack('Q*').first
#⇒ 7523094288207667809
您的代码会产生错误的结果,因为在转换为二进制后,字节应该是 reversed。
对于您问题的最后一部分,输出.unpack('Q')
不随较长输入字符串而改变的原因是因为格式指定了单个 64 位值,因此前 8 个字符之后的任何字符都将被忽略。如果您指定格式Q2
和 16 个字符的字符串,您将解码 2 个值:
> 'abcdefghihjklmno'.unpack('Q2')
=> [7523094288207667809, 8029475498074204265]
你会再次发现添加额外的字符不会改变结果:
> 'abcdefghihjklmnofoofoo'.unpack('Q2')
=> [7523094288207667809, 8029475498074204265]
的格式Q*
将返回与输入中 64 位的倍数一样多的值:
> 'abcdefghihjklmnopqrstuvw'.unpack('Q*')
=> [7523094288207667809, 8029475498074204265, 8608196880778817904]
> 'abcdefghihjklmnopqrstuvwxyz'.unpack('Q*')
=> [7523094288207667809, 8029475498074204265, 8608196880778817904]
推荐阅读
- c - 改进我的 C 编码并发现代码问题
- php - 如何在使用语句中检测不存在的类
- java - 如何拆分字符串并保留分隔符'='
- excel - 保存电子表格时删除特殊字符
- python - 如何计算运行 CNN 所需的 GPU
- mysql - 创建并保存 sql 转储到远程
- android - Kotlin 中的“_”符号是什么意思?
- c# - 无法在特定条件下迭代数组中的所有值?
- vpn - 网络问题 - mikrotik + Synology vpn
- python - ModuleNotFoundError:没有名为“tensorflow.python.tools”的模块;“tensorflow.python”不是一个包