ein*_*ica 6 c floating-point printf format-specifiers language-lawyer
考虑以下 printf 指令:
\nprintf("%# 01.1g", 9.8);\nRun Code Online (Sandbox Code Playgroud)\n它应该打印什么?
\n我正在 cppreference.com 上阅读g说明符的描述,其中显示(已删除的文本G):
\n\n根据值和精度将浮点数转换为十进制或十进制指数表示法。
\n对于g转换,将执行带有e或f样式的样式转换。
\n
如果非零,则令 P 等于精度;如果未指定精度,则令 P 等于精度;如果精度为 \xe2\x80\x8b0\xe2\x80\x8b,则令 P 等于精度。那么,如果使用e类型的\n转换将具有 X 的指数:\n
\n- 如果 P > X \xe2\x89\xa5 \xe2\x88\x924,则转换采用样式f和精度 P \xe2\x88\x92 1 \xe2\x88\x92 X。
\n- 否则,转换采用样式e和精度 P \xe2\x88\x92 1。
\n除非请求替代表示,否则尾随零将被删除,如果没有留下小数部分,小数点字符也会被删除。
\n
在我们的例子中,
\n"%# 01.1e",产生 9.8e+00(调整 GodBolt 程序,你会看到)。因此,转换应采用样式f和精度 P - 1 - X = 1 - 1 - 0 = 0,即"%# 01.0f",产生 10.。
...但这不是glibc产生的结果:我得到了 1.e01,也可以在 上看到GodBolt。
所以,
\n这是对 \xe2\x80\x9ca 与样式 \xe2\x80\x9d 的转换缺乏明确性,并且与和E的精度含义存在差异。Eg
使用 时E,精度是小数点后出现的位数,根据 C 2018 7.21.6.1 4。使用 时g,精度是有效数字的最大位数。这些不同;E小数点前有一位额外的数字,总共比其名义 \xe2\x80\x9c 精度多一位数字。\xe2\x80\x9d
因此,在考虑如何为 格式化 9.8 时%.1g,我们首先考虑如何将%.0E、 not 、 格式化为%.1E,%.1g和%.0E要求一位数字,而%.1E要求两位数字。对于%.0E,将生成 \xe2\x80\x9c1e+01\xe2\x80\x9d 。所以指数X是 1,而不是 0。