Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between %f and %lf in C?

Tags:

c

I saw these two parameters in a C example in a C book but the author didn't elaborate what the difference between the two are. I know that %f specifies that a float should take its place. I tried looking this up but had a hard time trying to find this w symbols. What about %lf?

like image 441
committedandroider Avatar asked Sep 16 '14 04:09

committedandroider


People also ask

Can you use %F for double?

We can print the double value using both %f and %lf format specifier because printf treats both float and double are same. So, we can use both %f and %lf to print a double value.

What is %f used for in C?

'%f': Print a floating-point number in normal (fixed-point) notation. See Floating-Point Conversions, for details.

What is the difference between %F and %G in C?

%f %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 %g represents the decimal format of the answer, depending upon whose length is smaller, comparing between %e and %f. Also removes succeeding zeros.


2 Answers

The short answer is that it has no impact on printf, and denotes use of float or double in scanf.

For printf, arguments of type float are promoted to double so both %f and %lf are used for double. For scanf, you should use %f for float and %lf for double.

More detail for the language lawyers among us below:


There is no difference between %f and %lf in the printf family. The ISO C standard (all references within are from C11), section 7.21.6.1 The fprintf function, paragraph /7 states, for the l modifier (my emphasis):

Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument; that a following n conversion specifier applies to a pointer to a long int argument; that a following c conversion specifier applies to a wint_t argument; that a following s conversion specifier applies to a pointer to a wchar_t argument; or has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.

The reason it doesn't need to modify the f specifier is because that specifier already denotes a double, from paragraph /8 of that same section where it lists the type for the %f specifier:

A double argument representing a floating-point number is converted to decimal notation

That has to do with the fact that arguments following the ellipse in the function prototype are subject to default argument promotions as per section 6.5.2.2 Function calls, paragraph /7:

The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.

Since printf (and the entire family of printf-like functions) is declared as int printf(const char * restrict format, ...); with the ellipsis notation, that rule applies here. The default argument promotions are covered in section 6.5.2.2 Function calls, paragraph /6:

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.


For the scanf family, it mandates the use of a double rather than a float. Section 7.21.6.2 The fscanf function /11:

Specifies that a following d, i, o, u, x, X, or n conversion specifier applies to an argument with type pointer to long int or unsigned long int; that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to double; or that a following c, s, or [ conversion specifier applies to an argument with type pointer to wchar_t.

This modifies the /12 paragraph of that section that states, for %f:

Matches an optionally signed floating-point number, infinity, or NaN, whose format is the same as expected for the subject sequence of the strtod function. The corresponding argument shall be a pointer to floating.

like image 52
paxdiablo Avatar answered Sep 28 '22 01:09

paxdiablo


For scanf, %f reads into a float, and %lf reads into a double.

For printf: In C99 and later, they both are identical, and they print either a float or a double. In C89, %lf caused undefined behaviour although it was a common extension to treat it as %f.

The reason that one specifier can be used for two different types in printf is because of the default argument promotions; arguments of type float are promoted to double when used to call a function and not matching a parameter in a function prototype. So printf just sees a double in either case.

like image 20
M.M Avatar answered Sep 28 '22 03:09

M.M