C中的高精度划分

时间:2013-08-28 23:22:14

标签: c math precision floating-point-precision

我想在不损失C精度的情况下进行以下计算。

uint64_t ts_1 = 0x5212cb03ca115ac0; 
uint64_t ts_2 = 0x5212cb03ca115cc0; 
uint64_t ts_delta = (ts_2 - ts_1)

double scale_factor = ts_delta/(2^32)

我得到ts_delta的值为0x200.但是scale_factor的值为15.000000。基本上我在计算过程中失去了精度。

如何在不失精度的情况下完成。?

这是一个关于我如何尝试打印的简短自包含示例。

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main()
{
        uint64_t ts_1 = 0x5212cb03ca115ac0;
        uint64_t ts_2 = 0x5212cb03ca115cc0;
        uint64_t ts_delta = (ts_2 - ts_1);
        double scale_factor = ((double)ts_delta) / (((uint64_t)1) << 32);

        printf("ts_delta %"PRIx64" scale factor %f \n",ts_delta,scale_factor);

        return 0;
}

2 个答案:

答案 0 :(得分:3)

你没有做你认为你正在做的计算。 C中的^运算符执行取幂,它执行按位异或。您实际上将ts_delta除以2 xor 32 == 34。我不确定你是如何得到15.000000的,应该是15.058823529411764。{/ p>

你想要做的计算用C表示:

double scale_factor = ((double)ts_delta) / (((uint64_t)1) << 32);

编辑:从另一个答案:如果你的编译器支持C99的十六进制浮点文字,你也可以编写

double scale_factor = ts_delta * 0x1p-32;

这样编写,不需要强制转换,因为乘法的一边已经是double,所以另一边的整数将被转换为匹配。不幸的是,有几个编译器有uint64_t但没有C99的其他功能,例如最近的MSVC。

答案 1 :(得分:2)

您需要计算浮点值,并获得表达式以提升权力。您可以使用标准函数ldexp

#include <math.h>

double scale_factor = ldexp(ts_2 - ts_1, -32)

或者只是乘以一个常数(感谢@Eric Postpischil!):

double scale_factor = (ts_2 - ts_1) * 0x1p-32;