Mar*_*ery 7 c language-agnostic floating-point printf format-specifiers
该%g说明符似乎并不在多数来源记录它运行得的方式行事.
根据我发现的大多数来源,在使用printf说明符的多种语言中,说明%g符应该等同于%f或者%e- 对于提供的值产生较短的输出.例如,在撰写此问题时,cplusplus.com表示说明g符意味着:
使用最短的表示:
%e或%f
而PHP手册说这意味着:
g - %e和%f中的较短者.
而且这里有一个堆栈溢出的答案是声称,
%g使用最短的表示.
而Quora的回答声称:
%g以这两个表示中最短的方式打印数字
但这种行为不是我在现实中看到的.如果我编译并运行该程序(作为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;
}
Run Code Online (Sandbox Code Playgroud)
...然后我看到这个输出:
1.234560e+05
123456.000000
123456
1.234567e+06
1234567.000000
1.23457e+06
Run Code Online (Sandbox Code Playgroud)
显然,%g输出不完全匹配任一的%e或%f输出,用于任一x或y以上.更重要的是,它看起来不像%g是最小化输出长度; y可能已经被格式化更简洁,如果像x,它没有被科学记数法印.
我上面引用的所有资料都在向我说谎吗?
我在支持这些格式说明符的其他语言中看到了相同或相似的行为,也许是因为它们引用了printfC函数族.例如,我在Python中看到了这个输出:
>>> print('%g' % 123456.0)
123456
>>> print('%g' % 1234567.0)
1.23457e+06
Run Code Online (Sandbox Code Playgroud)
在PHP中:
php > printf('%g', 123456.0);
123456
php > printf('%g', 1234567.0);
1.23457e+6
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
控制这种输出的逻辑是什么?
Mar*_*ery 14
这是C11标准中g/ 说明符的完整描述G:
甲双表示浮点数参数被转换风格
f或e(或风格F或E在A的情况下G转换说明),这取决于转换的值和精度.设P等于非零的精度,如果省略精度则设为6,如果精度为零则设为1.然后,如果带样式的转换E的指数为X:如果P > X ≥-4,转化是用式
f(或F)和精密对- (X + 1) .
否则,转换是使用样式e(或E)和精度P - 1.最后,除非使用#标志,否则从结果的小数部分删除任何尾随零,如果没有剩余小数部分,则删除小数点字符.
甲双参数表示无穷大或NaN被转换的样式
f或F转换说明.
这种行为有点类似于简单地用最短的表示出来的%f和%e,但不等同.有两个重要的区别:
%g,这可能导致输出%g符将不完全匹配什么要么 %f还是%e会一直产生.%f样式或%e样式格式的决定完全基于%e样式表示法所需的指数大小,并不直接取决于哪个表示更短.有些情况下,在这种规则导致几种情况%g选择较长的代表性,如你问题中所示的地方%g使用,尽管这使得再输出4个字符比它需要的是科学记数法.如果C标准的措辞很难解析,Python文档提供了相同行为的另一种描述:
一般格式.对于给定的精度,将数字舍入为p>=1有效数字,然后根据其大小以定点格式或科学记数法格式化结果.p精确的规则如下:假设使用表示类型
和精度格式化的结果'e'将具有指数p-1.然后,如果exp,数字格式化为演示文稿类型-4<=exp<p和精度'f'.否则,使用表示类型p-1-exp和精度格式化数字'e'.在这两种情况下,从有效数字中删除无关紧要的尾随零,如果后面没有剩余数字,则也会删除小数点.p-1正和负无穷大,正的和负的零,和NaN,被格式化为
精度,inf,-inf,0和-0的分别,而不管精度.nan被视为等于精度0.默认精度为1.6
互联网上的许多消息来源声称%g只选择最短的%e并且%f完全错误.