将精确表示分配给浮点值

时间:2017-09-03 23:08:44

标签: c++ floating-point precision

this question中,OP试图在大型程序中孤立一个难以捉摸的错误。他观察了一些double值,然后尝试将它们硬编码为较小测试程序的输入。 ideea非常适合隔离这样的错误。

然而,所选择的方法违反了字符串别名规则,引入了UB,因此测试完全不可靠:

  1. 在调试器中查看表达式:

    +------------------------+----------------------|
    | Watch Expression       | Value                |
    +------------------------+----------------------|
    | *(long long int *)(&a) | 4594681439063077250  |
    +------------------------+----------------------|
    
  2. 然后在测试程序中分配它:

    double a;
    *(long long int *)(&a) = 4594681439063077250;
    
  3. (我强烈怀疑)他这样做是为了保持精确的double值,一点一滴。

    问题:如何将精确值分配给double - 逐位 -  在调试会话中观察到了什么?

3 个答案:

答案 0 :(得分:4)

Hexadecimal representation是分配浮点值的精确位表示的好方法。如果您因为尚未使用C ++ 17而无法使用文字,请注意strtod会识别此格式。

答案 1 :(得分:0)

这可以通过将double表示为char

的数组来实现
double as_double = 0.0;
uint64_t as_uint64 = 4594681439063077250 ;

static_assert(sizeof(double) == sizeof(uint64_t), "");
memcpy(&as_double, &as_uint64_t, sizeof(double));

答案 2 :(得分:0)

我对严格别名规则的解释说,这将是UB

uint64_t x = 4594681439063077250;
double * a = (double *) & x;

你的代码很好。