在C语言中,%g和%f有什么区别?

41

我正在学习K&R的《C程序设计语言》。在书中,要输出double类型变量,需要使用以下语句:

printf("\t%g\n", sum += atof(line));

在这里,sum被声明为double类型。请问有人能帮我解决何时使用%g来表示double或float类型,以及%g和%f之间的区别吗?


1
关于你的第二点:printf 函数中的 float 参数会自动转换为 double,因此不需要特定的 float 指示符(因为 float 值无法达到那个范围)。 - pmg
7个回答

52

它们都是浮点数输入/输出的例子。

%g 和 %G 是科学计数法浮点数 %e 和 %E 的简化。

%g 将接受一个可以表示为 %f(简单浮点数或双精度浮点数)或 %e(科学计数法)的数字,并将其作为两者中较短的一种返回。

您的打印语句的输出取决于 sum 的值。


8
我认为应该接受这个答案。这个答案既精确又富有信息量。 - user366312
3
尽管这条回答目前在页面上是分数最高的,但事实上是错误的。%g 的输出不必匹配 %f%e 中的任何一个,并且 %g 的选择是否使用科学计数法不取决于哪种表示法更短。请参见 https://dev59.com/R1QJ5IYBdhLWcg3wSj4C,我在那里展示了反例。unwind 在这里的被接受的回答是正确的,但此回答不正确。 - Mark Amery

33

请参考任何参考手册,如man页面:

f,F

双精度参数四舍五入并以样式[-]ddd.ddd转换为十进制符号。小数点字符后的数字位数等于精度规范。 如果缺少精度,则将其视为6; 如果显式指定精度为零,则不会出现小数点字符。 如果出现小数点,则在其前至少出现一个数字。 (SUSv2不知道F,并表示可以提供无限大和NaN的字符串表示形式。 C99标准指定无限大用'[-]inf'或'[-]infinity'表示,而NaN的情况则以'nan'开头的字符串表示,对于f转换,'[-]INF'或'[-]INFINITY'或'NAN *'表示。)

g,G

双精度参数按样式f或e(或G转换的F或E)进行转换。 精度规定了有效数字的数量。 如果缺少精度,则给出6个数字; 如果精度为零,则将其视为1。 如果来自其转换的指数小于-4或大于或等于精度,则使用样式e。 结果的小数部分中删除尾随零;只有在小数点后至少跟随一个数字时,才会出现小数点。


6
E = 指数表达式,简单地表示为 power(10, n) 或 10 ^ n
F = 分数表达式,默认精度为6位小数
G = 通用表达式,以一种简洁的方式显示数字(但真的吗?)
请参考以下示例,
代码
void main(int argc, char* argv[])  
{  
        double a = 4.5;
        printf("=>>>> below is the example for printf 4.5\n");
        printf("%%e %e\n",a);
        printf("%%f %f\n",a);
        printf("%%g %g\n",a);
        printf("%%E %E\n",a);
        printf("%%F %F\n",a);
        printf("%%G %G\n",a);
          
        double b = 1.79e308;
        printf("=>>>> below is the exbmple for printf 1.79*10^308\n");
        printf("%%e %e\n",b);
        printf("%%f %f\n",b);
        printf("%%g %g\n",b);
        printf("%%E %E\n",b);
        printf("%%F %F\n",b);
        printf("%%G %G\n",b);

        double d = 2.25074e-308;
        printf("=>>>> below is the example for printf 2.25074*10^-308\n");
        printf("%%e %e\n",d);
        printf("%%f %f\n",d);
        printf("%%g %g\n",d);
        printf("%%E %E\n",d);
        printf("%%F %F\n",d);
        printf("%%G %G\n",d);
}  

输出
=>>>> below is the example for printf 4.5
%e 4.500000e+00
%f 4.500000
%g 4.5
%E 4.500000E+00
%F 4.500000
%G 4.5
=>>>> below is the example for printf 1.79*10^308
%e 1.790000e+308
%f 178999999999999996376899522972626047077637637819240219954027593177370961667659291027329061638406108931437333529420935752785895444161234074984843178962619172326295244262722141766382622299223626438470088150218987997954747866198184686628013966119769261150988554952970462018533787926725176560021258785656871583744.000000
%g 1.79e+308
%E 1.790000E+308
%F 178999999999999996376899522972626047077637637819240219954027593177370961667659291027329061638406108931437333529420935752785895444161234074984843178962619172326295244262722141766382622299223626438470088150218987997954747866198184686628013966119769261150988554952970462018533787926725176560021258785656871583744.000000
%G 1.79E+308
=>>>> below is the example for printf 2.25074*10^-308
%e 2.250740e-308
%f 0.000000
%g 2.25074e-308
%E 2.250740E-308
%F 0.000000
%G 2.25074E-308

1
终于有一个合适的例子了。 - 0xB00B

3
如Unwind所指出,f和g提供不同的默认输出。简单来说,如果您更关心小数点后面的细节,我会选择f;如果您想要适应大量数字,请选择g。从一些尘封的记忆来看,如果您打印数字表格,当值较小时,f非常好,因为所有内容都保持对齐,但如果您的数字变大并且布局很重要,则需要使用类似于g的函数。当您的数字趋向于非常小或非常大但从未接近十时,e更有用。另一种方法是指定输出格式,以便每次获得表示您的数字的相同字符数。抱歉回答含糊,但这是一个主观的输出问题,只有在生成的字符数很重要或所表示的值的精度时才会得到固定的答案。

0

%g 可以去除浮点数末尾的零,

可以打印出整数 upto 10**6,精度超过6位时使用科学计数法输出

123456 输出 123456

1234567 输出 1.23457e+06

可以打印出浮点数 > 10**-4,精度超过6位时进行四舍五入

1.23456 输出 1.23456

1.234567 输出 1.23457

如果浮点数 < 10**-4,则将其保留到小数点后4位,否则使用ne-0p表示

0.0001 输出 0.0001

0.000001 输出 1e-06

0.12345678 输出 0.123457

%G 的功能与 %g 相同,但指数形式的 e 会变成 E


0

所有三个格式说明符 %e、%f 和 %g 都用于在 C 中处理浮点和双精度数据类型。

%e 表示以指数形式(科学计数法)表示数据。

%f 表示以正常的小数形式表示数据,保留六位小数,不过您可以控制输出多少位小数。

%g 表示十进制格式并删除后续的零。

以下是在 C 代码中如何使用 %e、%f 和 %g 的示例:

#include <stdio.h>

int main() 
{ 
    double ans = 123.45; 
    
    printf("Printing using %%f %f\n",ans); 
    printf("Printing using %%e %e\n",ans); 
    printf("Printing using %%g %g\n\n\n",ans);
    // 
    
    
    ans = 123.45e8; // scientific way of writing 123.45 * 10^8
    
    printf("Printing using %%f %f\n",ans); 
    printf("Printing using %%e %e\n",ans); 
    printf("Printing using %%g %g\n\n\n",ans); 
    
    
    ans = 123.45e-8; // scientific way of writing 123.45 * 10^(-8) i,e. 0.0000012345
    
    // %f has upto 6 digits precision
    // 0.0000012345 converted to 0.000001 (max 6 precision allowed)
    printf("Printing using %%f %f\n",ans); 
    printf("Printing using %%e %e\n",ans); 
    printf("Printing using %%g %g\n",ans); 
    
    return 0;
}

输出将会是:

Printing using %f 123.450000
Printing using %e 1.234500e+02
Printing using %g 123.45

Printing using %f 12345000000.000000
Printing using %e 1.234500e+10
Printing using %g 1.2345e+10

Printing using %f 0.000001
Printing using %e 1.234500e-06
Printing using %g 1.2345e-06

-4

%f和%g的作用是相同的。唯一的不同之处在于%g是%f的更短形式。也就是说,在%f中,小数点后的精度比%g大。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接