Mir*_*ler 8 c floating-point double printf libgcc
我正在尝试优化 double->text 转换(试图击败 grissu、ryu 等...)。
在这样做的同时,我将我的结果与sprintf
输出进行比较。现在我遇到了上面有趣的案例。
printf("%.15e", 1e23);
Run Code Online (Sandbox Code Playgroud)
(例如 glibc)打印
9.999999999999999e+22
虽然我的日常打印
1.000000000000000e+23
现在这两个数字与“真实值”的距离相同,并且将这两个值转换回(例如使用atof
)会产生相同的双精度值。
但是,我相信我的结果满足“四舍五入”规则(这就是它走这条路的原因)。
哪个结果更正确?
1e23
是典型地不完全表示为一个double
。
2个最接近的选择是:
// %a v %f
0x1.52d02c7e14af6p+76 99999999999999991611392.000000
0x1.52d02c7e14af7p+76 100000000000000008388608.000000
Run Code Online (Sandbox Code Playgroud)
从 100000000000000000000000.0 中,有两个 8388608.0,一个在上面,一个在下面。
通常,在平局情况下选择的一个是偶数个。(请参阅十六进制格式的最后一位。)
99999999999999991611392.000000 是赢家,因此"9.999999999999999e+22"
预期输出为 。
当打印更多的DBL_DIG
(15) 位有效数字时,("%.15e"
打印 16 位有效数字)这个问题是可能的,因为代码正在有效地进行文本double
- -文本往返并超出double
可以往返的范围。
我正在尝试优化双 > 文本转换
我建议也使用"%a"
以获得更深入的理解。