%g说明符似乎并不像大多数来源将其记录为那样。

根据我发现的大多数资料,在使用printf说明符的多种语言中,%g说明符应等效于%f%e-以提供的值为单位,它们会产生较短的输出。例如,在编写此问题时,g说明符表示的cplusplus.com says是:



PHP manual says的意思是:



还有here's a Stack Overflow answer声称



a Quora answer声称:



但是这种行为不是我在现实中看到的。如果我编译并运行该程序(作为C或C++,这是一个有效的程序,两者的行为相同):

#include <stdio.h>

int main(void) {
    double x = 123456.0;
    printf("%e\n", x);
    printf("%f\n", x);
    printf("%g\n", x);
    printf("\n");

    double y = 1234567.0;
    printf("%e\n", y);
    printf("%f\n", y);
    printf("%g\n", y);
    return 0;
}

...然后我看到以下输出:
1.234560e+05
123456.000000
123456

1.234567e+06
1234567.000000
1.23457e+06

显然,上述%g%e%f输出与xy输出都不完全匹配。而且,%g似乎也没有使输出长度最小化。如果yx一样,未以科学计数法进行打印,则它的格式可能更简洁。

我上面引用的所有消息来源都是骗我的吗?

在支持这些格式说明符的其他语言中,我看到了相同或相似的行为,可能是因为它们在幕后调用了C函数的printf家族。例如,我在Python中看到以下输出:
>>> print('%g' % 123456.0)
123456
>>> print('%g' % 1234567.0)
1.23457e+06

在PHP中:
php > printf('%g', 123456.0);
123456
php > printf('%g', 1234567.0);
1.23457e+6

在Ruby中:
irb(main):024:0* printf("%g\n", 123456.0)
123456
=> nil
irb(main):025:0> printf("%g\n", 1234567.0)
1.23457e+06
=> nil

控制此输出的逻辑是什么?

最佳答案

这是C11标准中g/G说明符的完整描述:



此行为有点类似于简单地使用%f%e中的最短表示形式,但并不等效。有两个重要区别:

  • 使用%g时,结尾的零(可能还有小数点)会被剥夺,这可能导致%g说明符的输出与%f%e生成的内容不完全匹配。
  • 是否使用%f -style或%e -style格式的决定完全基于%e -style表示法所需的指数大小,而不直接取决于哪种表示形式会更短。在多种情况下,此规则会导致%g选择更长的表示形式,例如在问题中所示的一种情况,其中%g使用科学计数法,即使这会使输出比需要的长4个字符。

  • 如果很难解析C标准的措辞,则Python documentation提供了相同行为的另一种描述:



    互联网上许多声称%g只是从%e%f中选出最短的消息来源是完全错误的。

    关于c - %g printf说明符到底是什么意思?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54162152/

    10-11 21:46