Qt 等效于 Perl 打包/解包
Posted
技术标签:
【中文标题】Qt 等效于 Perl 打包/解包【英文标题】:Qt equivalent of Perl pack/unpack 【发布时间】:2014-05-31 19:28:04 【问题描述】:以下是十六进制数据及其代表的浮点数的列表:
e77ed8f8201a5440 = 78.4083
0000000000005540 = 82
4c541773e2185040 = 62.3888
0000000000005640 = 86
以下 Perl 代码使用 pack/unpack 来获得几乎正确的转换(精确到 2):
use strict;
use warnings;
while (<DATA>)
chomp;
my $dat = $_;
my $hval = pack "H*", $dat;
my $fval = unpack "F", $hval;
print "$dat .. $fval \n";
__DATA__
e77ed8f8201a5440
0000000000005540
4c541773e2185040
0000000000005640
输出:
e77ed8f8201a5440 .. 80.408262454435
0000000000005540 .. 84
4c541773e2185040 .. 64.3888213851762
0000000000005640 .. 88
这个打包/解包的 Qt/C 等价物是什么,或者它用于将十六进制“转换”为浮点数的算法是什么?
【问题讨论】:
【参考方案1】:这个打包/解包的 Qt/C 等价物是什么,
#include <QString>
#include <QByteArray>
#include <algorithm>
#include <cstring>
...
QString value="e77ed8f8201a5440";
// convert the hex string to an array of bytes
QByteArray arr=QByteArray::fromHex(value);
// reverse if necessary
#if Q_BYTE_ORDER==Q_BIG_ENDIAN
std::reverse(arr.begin(), arr.end());
#endif
// if everything went right, copy the bytes in a double
if(arr.size()==sizeof(double))
double out;
std::memcpy((void *)&out, (void *)arr.data(), sizeof(double));
// ...
也许您也可以使用 QtEndian(而不是有条件地调用 std::reverse
而不是 arr
),但目前尚不清楚这些函数是否可以在除整数类型之外的任何东西上调用。
或者它用于将十六进制“转换”为浮点数的算法是什么?
您拥有的数据只是小端 IEEE-754 double
的原始内容的转储; “算法”只是将十六进制解码为其表示的字节并将它们复制到double
变量(如果我们在大端机器上,则反转字节顺序)。
【讨论】:
@ikegami:呃,对不起,你是对的,我不知道为什么我一直认为它们是花车。 谢谢 - 我正在读取的数据来自 QByteArray,所以这个答案正是我所需要的。非常感谢。 @TenG:在这种情况下,请记住,如果您的QByteArray
包含的内容多于一个 double
,则必须将 reverse
应用于 8 字节块(并且不是整个 QByteArray`)。【参考方案2】:
pack 'H*'
是从十六进制字符对到相应字节的conversion。
unpack 'F'
是 double
的转换。这可以使用memcpy
来完成(以避免对齐问题),如下所示:
#include <stdio.h>
#include <string.h>
int main()
char bytes[] = 0xE7, 0x7e, 0xd8, 0xf8, 0x20, 0x1a, 0x54, 0x40 ;
double d;
memcpy(&d, bytes, sizeof(bytes));
printf("%lf\n", d);
return 0;
输出:
$ gcc -o a a.c && a
80.408262
请注意,这将在大端机器上失败。您必须先反转字节,然后再将它们复制到这些机器上。
【讨论】:
这是C。我不知道Qt
是什么。
谢谢 - 这是一个很大的帮助。我不明白它是如何工作的,但我可以稍后解决。以上是关于Qt 等效于 Perl 打包/解包的主要内容,如果未能解决你的问题,请参考以下文章