我想在不损失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;
}
答案 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;