40

I was going through The C programming Language by K&R. Here in a statement to print a double variable it is written

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

where sum is declared as double. Can anybody please help me out when to use %g in case of double or in case of float and whats the difference between %g and %f.

unwind
  • 391,730
  • 64
  • 469
  • 606
Shashi Bhushan
  • 1,481
  • 3
  • 16
  • 20
  • 1
    as to your 2nd point: a `float` argument to `printf` is automagically converted to `double`, so there is no need for a specific `float` specifier (because it is impossible for a `float` value to get that far). – pmg May 06 '11 at 15:27

7 Answers7

50

They are both examples of floating point input/output.

%g and %G are simplifiers of the scientific notation floats %e and %E.

%g will take a number that could be represented as %f (a simple float or double) or %e (scientific notation) and return it as the shorter of the two.

The output of your print statement will depend on the value of sum.

user366312
  • 16,949
  • 65
  • 235
  • 452
Daniel Nill
  • 5,539
  • 10
  • 45
  • 63
  • 8
    I think this answer was to be accepted. This answer is precise and informative at the same time. – user366312 Oct 30 '11 at 17:09
  • 3
    -1; despite this currently being the highest-score answer on the page by a significant margin, it's factually wrong. The output of `%g` needn't match *either* `%f` or `%e`, and the choice `%g` makes about whether to use scientific notation does not depend upon which representation would be shorter. See https://stackoverflow.com/q/54162152/1709587 where I show counterexamples. The [accepted answer](https://stackoverflow.com/a/5913115/1709587) by unwind here is correct, but this one isn't. – Mark Amery Jan 22 '19 at 14:37
33

See any reference manual, such as the man page:

f,F

The double argument is rounded and converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. If a decimal point appears, at least one digit appears before it. (The SUSv2 does not know about F and says that character string representations for infinity and NaN may be made available. The C99 standard specifies '[-]inf' or '[-]infinity' for infinity, and a string starting with 'nan' for NaN, in the case of f conversion, and '[-]INF' or '[-]INFINITY' or 'NAN*' in the case of F conversion.)

g,G

The double argument is converted in style f or e (or F or E for G conversions). The precision specifies the number of significant digits. If the precision is missing, 6 digits are given; if the precision is zero, it is treated as 1. Style e is used if the exponent from its conversion is less than -4 or greater than or equal to the precision. Trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit.

unwind
  • 391,730
  • 64
  • 469
  • 606
6

E = exponent expression, simply means power(10, n) or 10 ^ n

F = fraction expression, default 6 digits precision

G = gerneral expression, somehow smart to show the number in a concise way (but really?)

See the below example,

The code

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);
}  

The output

=>>>> 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
LinconFive
  • 1,718
  • 1
  • 19
  • 24
3

As Unwind points out f and g provide different default outputs.

Roughly speaking if you care more about the details of what comes after the decimal point I would do with f and if you want to scale for large numbers go with g. From some dusty memories f is very nice with small values if your printing tables of numbers as everything stays lined up but something like g is needed if you stand a change of your numbers getting large and your layout matters. e is more useful when your numbers tend to be very small or very large but never near ten.

An alternative is to specify the output format so that you get the same number of characters representing your number every time.

Sorry for the woolly answer but it is a subjective out put thing that only gets hard answers if the number of characters generated is important or the precision of the represented value.

TafT
  • 2,764
  • 6
  • 33
  • 51
0

%g removes trailing zeros in floats,

prints (integer) upto 10**6 , after that in e+ upto precision 6

123456 gives 123456

1234567 gives 1.23457e+06

prints (float > 10** -4 ) upto precision 6 , after that rounds off to pre. 6

1.23456 gives 1.23456

1.234567 gives 1.23457

print (float < 10** -4 ) upto precision 4 , else in ne-0p

0.0001 gives 0.0001

0.000001 gives 1e-06

0.12345678 gives 0.123457

%G does the same , but exp(e) becomes exp(E)

0

All the three format specifiers %e, %f and %g are used to work with float and double data types in C.

%e represents the data in exponential power(scientific format).

%f represents the data in normal decimal form, upto six decimal places, although you can control, that upto how many decimal places did you want your output.

%g represents the decimal format and removes succeeding zeros.

example how to use %e, %f and %g in a c code:

#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;
}

the output would be:

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
A. Rokbi
  • 503
  • 2
  • 8
-4

%f and %g does the same thing. Only difference is that %g is the shorter form of %f. That is the precision after decimal point is larger in %f compared to %g

rancho
  • 145
  • 9
  • 12