2

我想用十六进制常量初始化一个双精度。

double dbl = 0xFEDCBA9876543212;
printf("dbl: %llX\n", (uint64_t)dbl);

我希望看到输出:

dbl: FEDCBA9876543212

但我得到:

dbl: FEDCBA9876543000

为什么会这样,为什么最后 3 个字节被丢弃?

4

5 回答 5

4

您正在使用 64 位值来初始化一个 double,它只包含 53 个有效位。有一点舍入,剩下的位就丢失了。

于 2014-09-18T22:17:35.120 回答
2

如果您想确切知道双精度的值,请使用双精度的十六进制格式,

0x1.01234567898abcp-12

然后printf("%p", number);在另一端组装好号码后打印号码。如果您的位数正确,则该数字应与输入相匹配。

于 2014-09-18T22:46:21.223 回答
2

如果你只是想做一个 memcpy 风格的交易,你可以尝试:

uint64_t x = 0xFEDCBA9876543212;
double dbl = *reinterpret_cast<double *>(&x);

此外,您的测试可能没有按照您的意愿进行:

我的测试:

#include <cstdint>
#include <cstdio>

int main (void) {
  // Move the underlying hex value through multiple types
  uint64_t x = 0xFEDCBA9876543212;
  double dbl = *reinterpret_cast<double *>(&x);
  uint64_t y = *reinterpret_cast<uint64_t *>(&dbl);

  // Check integrity of the result
  printf("dbl: %llX\n", (uint64_t)dbl);  //your test
  printf("x: %llx\ny: %llx\n", x, y);  //my test

  return 0;
}

输出:

dbl: 8000000000000000
x: fedcba9876543212
y: fedcba9876543212

如您所见,即使您当前的测试产生了意外的输出,底层二进制值在从xdbl传递时仍然保持不变。yprintf("dbl: %llX\n", (uint64_t)dbl);

于 2014-09-18T22:18:50.217 回答
1

double精度是 53 bits,这就是为什么你在剩余位置上得到零的原因。

于 2014-09-18T22:17:10.813 回答
0

除了接受的答案,您还可以使用联合

union
{
    long long _double_exact;
    double _double;
};
double_exact = 0xFEDCBA9876543212;
于 2020-04-22T00:14:42.377 回答