8

我正在尝试优化双-> 文本转换(试图击败 grissu、ryu 等......)。

在这样做的同时,我将我的结果与sprintf输出进行比较。现在我遇到了上述有趣的案例。

printf("%.15e", 1e23);

(例如 glibc)打印

9.999999999999999e+22

而我的日常打印

1.000000000000000e+23

现在这两个数字与“真实值”的距离相同,并且将这两个值转换回来(例如 with atof)会产生相同的双精度值。

但是,我相信我的结果满足“四舍五入”规则(这就是它采用这种方式的原因)。

哪个结果更正确?

4

1 回答 1

5

1e23通常不完全表示为adouble

最接近的 2 个选择是:

// %a           v     %f 
0x1.52d02c7e14af6p+76  99999999999999991611392.000000
0x1.52d02c7e14af7p+76 100000000000000008388608.000000

从 100000000000000000000000.0 开始都有 8388608.0,一个在上面,一个在下面。

通常情况下,在平局中选择的是偶数。(请参见十六进制格式的最后一位。)

"9.999999999999999e+22"99999999999999991611392.000000 是获胜者,因此预期输出为 。

当使用更多DBL_DIG(15) 个有效数字打印时,("%.15e"打印 16 个有效数字)这个问题是可能的,因为代码正在有效地进行文本double往返并超出了double可以往返的范围。


我正在尝试优化双->文本转换

我建议也使用"%a"以获得更深入的了解。

于 2021-08-22T07:51:00.997 回答