考虑以下printf指令:
printf("%# 01.1g", 9.8);
它应该打印什么?
我正在阅读cppreference.com上关于g格式说明的描述,其中说(删除了G
的文本):
根据值和精度,将浮点数转换为十进制或十进制指数表示法。
对于使用样式e或f的g转换,将执行以下操作:
如果非零,则令P等于精度;如果未指定精度,则令P等于6;如果精度为0,则令P等于1。然后,如果使用样式e进行转换会得到指数X:
- 如果P > X ≥ −4,则使用样式f进行转换,精度为P − 1 − X。
- 否则,使用样式e进行转换,精度为P − 1。
除非要求使用替代表示法,否则会删除尾随的零,并且如果没有小数部分,则删除小数点字符。
在我们的情况下,
- P = 1,明确指定。
- X = 0,因为“使用样式e进行转换”,即
"%# 01.1e"
,得到9.8e+00
(调整Godbolt程序,你就会看到)。 - 1 > 0 >= -4 成立。
因此,转换应该使用样式f和精度P - 1 - X = 1 - 1 - 0 = 0,即"%# 01.0f"
,得到10.
。
...但这并不是glibc生成的结果:我得到的是1.e01
,也可以在Godbolt上看到。
所以:
- 我是否误读了引用的文本?
- cppreference.com错了吗?
- 这难道是glib 2.36的一个错误?
g
格式的精神;应该恰好有P位数字(或者更少,如果我们要求去除尾部的零)。 - Eric Postpischilg
格式的精神;应该恰好有P位数字(或者更少,如果我们要求去除尾部的零)。 - Eric Postpischile
格式,在你引用的段落的第二个项目中会发生什么;所使用的精度是P − 1。因此,比较 P > X 是在考虑“如果按照第二个项目打印,会发生什么?”它在选择使用e
和精度 P − 1 或者使用f
和精度 P − 1 − X 之间进行选择,所以应该使用与第二个项目相关联的 X。 - Eric Postpischil