What is the correct format specifier for double
in printf? Is it %f
or is it %lf
? I believe it's %f
, but I am not sure.
Code sample
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
"%lf"
is undefined; in C99 and C11 libraries it is defined to be the same as "%f"
.
%lf
is the correct format specifier for double
. But it became so in C99. Before that one had to use %f
.
"%f"
is the (or at least one) correct format for a double. There is no format for a float
, because if you attempt to pass a float
to printf
, it'll be promoted to double
before printf
receives it1. "%lf"
is also acceptable under the current standard -- the l
is specified as having no effect if followed by the f
conversion specifier (among others).
Note that this is one place that printf
format strings differ substantially from scanf
(and fscanf
, etc.) format strings. For output, you're passing a value, which will be promoted from float
to double
when passed as a variadic parameter. For input you're passing a pointer, which is not promoted, so you have to tell scanf
whether you want to read a float
or a double
, so for scanf
, %f
means you want to read a float
and %lf
means you want to read a double
(and, for what it's worth, for a long double
, you use %Lf
for either printf
or scanf
).
1. C99, §6.5.2.2/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." In C++ the wording is somewhat different (e.g., it doesn't use the word "prototype") but the effect is the same: all the variadic parameters undergo default promotions before they're received by the function.
Given the C99 standard (namely, the N1256 draft), the rules depend on the function kind: fprintf (printf, sprintf, ...) or scanf.
Here are relevant parts extracted:
Foreword This second edition cancels and replaces the first edition, ISO/IEC 9899:1990, as amended and corrected by ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995, and ISO/IEC 9899/COR2:1996. Major changes from the previous edition include: %lf conversion specifier allowed in printf 7.19.6.1 The fprintf function 7 The length modifiers and their meanings are: l (ell) Specifies that (...) has no effect on a following a, A, e, E, f, F, g, or G conversion specifier. L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to a long double argument.
The same rules specified for fprintf
apply for printf
, sprintf
and similar functions.
7.19.6.2 The fscanf function 11 The length modifiers and their meanings are: l (ell) Specifies that (...) that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to double; L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to long double. 12 The conversion specifiers and their meanings are: a,e,f,g Matches an optionally signed floating-point number, (...) 14 The conversion specifiers A, E, F, G, and X are also valid and behave the same as, respectively, a, e, f, g, and x.
The long story short, for fprintf
the following specifiers and corresponding types are specified:
%f -> double
%Lf -> long double.
and for fscanf
it is:
%f -> float
%lf -> double
%Lf -> long double.
It can be %f
, %g
or %e
depending on how you want the number to be formatted. See here for more details. The l
modifier is required in scanf
with double
, but not in printf
.
l
(lowercase) modifier is for integer types (cplusplus.com/reference/clibrary/cstdio/printf), and L
is for floating point types. Additionally, the L
modifier expects a long double
, not a plain double
.
l
is not required in printf
for double
.
Format %lf
is a perfectly correct printf
format for double
, exactly as you used it. There's nothing wrong with your code.
Format %lf
in printf
was not supported in old (pre-C99) versions of C language, which created superficial "inconsistency" between format specifiers for double
in printf
and scanf
. That superficial inconsistency has been fixed in C99.
You are not required to use %lf
with double
in printf
. You can use %f
as well, if you so prefer (%lf
and %f
are equivalent in printf
). But in modern C it makes perfect sense to prefer to use %f
with float
, %lf
with double
and %Lf
with long double
, consistently in both printf
and scanf
.
scanf()
, "%f"
, "%lf"
match a float *, double *
, not float, double
as implied by the last line.
%Lf
(note the capital L
) is the format specifier for long doubles.
For plain doubles
, either %e
, %E
, %f
, %g
or %G
will do.
%g
and %G
?
Success story sharing
g++
rejects%lf
when compiling with-Wall -Werror -pedantic
:error: ISO C++ does not support the ‘%lf’ gnu_printf format
l
was an extension. The C99/11 and C++11 standards require the implementation to allow it.scanf
does wantdouble
s represented by%lf
: it complains that it expectedfloat *
and founddouble *
with just%f
.scanf
takes pointers to where to store what it reads, so needs to know how big the space being pointed-at is, whereasprintf
takes the values themselves, and "default argument promotions" mean both end up asdouble
s, so thel
is essentially optional.