将 double 投射到 int64_t 并返回而不会丢失信息

Cast double to int64_t and back without info lost

这个问题可能有人问过,但我搜索了没有找到答案。

我正在实现一个玩具虚拟机,其中操作码采用以下形式:

std::tuple<int8_t, int64_t, int64_t> // instruction op1, op2

我正在尝试将一个双精度值打包到一个操作数中,并在处理它时再次读回它。这不能可靠地工作。

double d = ...
auto a = static_cast<int64_t>(d);
auto b = static_cast<double>(a)
// sometimes, b != d

有没有办法将 double 的位表示打包成 int64_t,然后读回该位模式以获得与以前完全相同的 double?

使其工作的一种方法是将内存块重新解释为 int64_t/double,即进行指针转换:

double d = ...
auto *a = (int64_t*)&d;
auto *d2 = (double*)a;
auto b = *d2;
assert(d == b);

请注意,我们都假设 doubleint64_t 的大小相同(64 位)。我现在不记得它是否是标准的一部分。

static_cast 执行值转换 - 小数部分总是丢失。 memcpy 就是您所追求的。

double d = ... 
int64_t a;
memcpy(&a, &d, sizeof(a));
double d2;
memcpy(&d2, &a, sizeof(d2));

不过,我可能会将操作数设为 uniondouble 以及 int64_t(加上您的 VM 可能感兴趣的其他类型)。