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?
}
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.
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
"%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.
g++
rejects %lf
when compiling with -Wall -Werror -pedantic
: error: ISO C++ does not support the ‘%lf’ gnu_printf format
–
Regan l
was an extension. The C99/11 and C++11 standards require the implementation to allow it. –
Diskin -Wno-format
is enough to make it compile. –
Regan scanf
does want double
s represented by %lf
: it complains that it expected float *
and found double *
with just %f
. –
Sanfo scanf
takes pointers to where to store what it reads, so needs to know how big the space being pointed-at is, whereas printf
takes the values themselves, and "default argument promotions" mean both end up as double
s, so the l
is essentially optional. –
Candelaria 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 inprintf
7.19.6.1 The
fprintf
function7 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
function11 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
. –
Terrilyn l
is not required in printf
for double
. –
Ivers printf
, the length modifier l
is ignored in the case of floating point types because float arguments are always promoted to double. Jerry Coffin's answer has more information. –
Foot 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. –
Brickle %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
? –
Faires © 2022 - 2024 — McMap. All rights reserved.
"%lf"
is undefined; in C99 and C11 libraries it is defined to be the same as"%f"
. – Goer%lf
is the correct format specifier fordouble
. But it became so in C99. Before that one had to use%f
. – Uptodate