如何将字节从 uint64_t 转换为 double?
Posted
技术标签:
【中文标题】如何将字节从 uint64_t 转换为 double?【英文标题】:How to convert bytes from uint64_t to double? 【发布时间】:2020-12-29 10:42:14 【问题描述】:我有二进制文件,我从中读取 uint64_t
val(使用 little-endian)。现在我想将这个uint64_t
转换为double
(不仅仅是强制转换,而是如果我从文件中输入的数字,则正好是double
)。所以应该有相同的位表示。我该怎么做?
【问题讨论】:
memcpy
将uint64_t
变成double
您是将 64 位整数转换为双精度还是将 8 字节转换为 double
?
创建一个double
变量。将 uint64_t 分配给 double
变量。
@ThomasMatthews,它们将具有相同的值但不同的位表示。
@ThomasMatthews 来自问题:“所以应该具有相同的位表示。”
【参考方案1】:
简单的便携方式:
uint64_t u64 = read_from_file();
double d;
memcpy(&d, &u64, sizeof(d));
大多数编译器只会为此生成几条指令。
【讨论】:
@RichardMcFriendOluwamuyiwa:什么不起作用?代码是否无法将uint64_t
的位重新解释为double
,或者编译器是否会生成对memcpy()
的调用?什么CPU?什么编译器?有什么选择?【参考方案2】:
这是一种方法:
uint64_t val = someCodeThatReadsTheValue();
auto valPtr = &val;
double dVal = *reinterpret_cast<double*>(valPtr);
正如 cmets 中所指出的,这是未定义行为,尽管它适用于大多数编译器。
如果您不想信任您的编译器,您可以执行以下操作。
uint64_t val1 = someCodeThatReadsTheValue();
double val2;
char* p1 = reinterpret_cast<char*>(&val1);
char* p2 = reinterpret_cast<char*>(&val2);
for(int i = 0; i < sizeof(uint64_t); i++)
p2[i] = p1[i];
删除这个只是一个有趣的事实,使用memcpy
更容易,就像@chqrlie 的答案一样。除非你不能使用 C 标准库。
【讨论】:
是未定义的行为 当您通过不兼容的类型访问数据时,此解决方案会调用未定义的行为。 帮助阅读:en.cppreference.com/w/cpp/language/… 还有这个:gist.github.com/shafik/848ae25ee209f698763cffee272a58f8 @DavidC.Rankin 联合解决方案对 C 有效,但通过联合进行类型双关对 C++ 来说是未定义的行为。以上是关于如何将字节从 uint64_t 转换为 double?的主要内容,如果未能解决你的问题,请参考以下文章
如何将字节数组转换为 boost::multiprecision::uint128_t?
是否有一种定义明确且高性能的方式将双精度位转换为 uint64_t 并返回
从uint32_t [16]数组到uint32_t变量序列的64位副本
如何将 32 字符(0/1)的序列转换为 32 位(uint32_t)?