printf("%.15e", 1e23); 应该做什么?打印?
What should printf("%.15e", 1e23); print?
我正在尝试优化 double->text 转换(试图打败 grissu、ryu 等...)。
在这样做的同时,我将我的结果与 sprintf
输出进行比较。现在遇到了上面那个有趣的案例
printf("%.15e", 1e23);
(例如 glibc)打印
9.999999999999999e+22
当我的例程打印时
1.000000000000000e+23
现在这两个数字与“真实值”的距离相同,并且将这两个值转换回来(例如使用 atof
)会产生相同的双精度值。
但是,我相信我的结果满足“四舍五入”规则(这就是它采用这种方式的原因)。
哪个结果更正确?
1e23
是 typically 不完全表示为 double
。
最接近的两个选择是:
// %a v %f
0x1.52d02c7e14af6p+76 99999999999999991611392.000000
0x1.52d02c7e14af7p+76 100000000000000008388608.000000
从100000000000000000000000.0开始都有8388608.0,上面一个,下面一个
通常在平局案例中选择的是偶数。 (请参阅十六进制格式的最后一位。)
99999999999999991611392.000000 是获胜者,因此预计输出 "9.999999999999999e+22"
。
当打印更多 DBL_DIG
(15) 有效数字时,("%.15e"
打印 16 有效数字)这个 问题 是可能的,因为代码是有效的进行文本-double
-文本往返并超过 double
可以往返的范围。
I am experimenting with optimizing double->text conversion
我建议也使用 "%a"
来获得更深入的理解。
我正在尝试优化 double->text 转换(试图打败 grissu、ryu 等...)。
在这样做的同时,我将我的结果与 sprintf
输出进行比较。现在遇到了上面那个有趣的案例
printf("%.15e", 1e23);
(例如 glibc)打印
9.999999999999999e+22
当我的例程打印时
1.000000000000000e+23
现在这两个数字与“真实值”的距离相同,并且将这两个值转换回来(例如使用 atof
)会产生相同的双精度值。
但是,我相信我的结果满足“四舍五入”规则(这就是它采用这种方式的原因)。
哪个结果更正确?
1e23
是 typically 不完全表示为 double
。
最接近的两个选择是:
// %a v %f
0x1.52d02c7e14af6p+76 99999999999999991611392.000000
0x1.52d02c7e14af7p+76 100000000000000008388608.000000
从100000000000000000000000.0开始都有8388608.0,上面一个,下面一个
通常在平局案例中选择的是偶数。 (请参阅十六进制格式的最后一位。)
99999999999999991611392.000000 是获胜者,因此预计输出 "9.999999999999999e+22"
。
当打印更多 DBL_DIG
(15) 有效数字时,("%.15e"
打印 16 有效数字)这个 问题 是可能的,因为代码是有效的进行文本-double
-文本往返并超过 double
可以往返的范围。
I am experimenting with optimizing double->text conversion
我建议也使用 "%a"
来获得更深入的理解。