523

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?
}
Community
  • 1
  • 1
Leopard
  • 5,241
  • 3
  • 13
  • 4
  • 19
    If you're stuck with a C89 library, `"%lf"` is undefined; in C99 and C11 libraries it is defined to be the same as `"%f"`. – pmg Apr 29 '12 at 00:06
  • 1
    Your variant is as correct as it ever gets. `%lf` is the correct format specifier for `double`. But it became so in C99. Before that one had to use `%f`. – AnT May 07 '16 at 19:59

5 Answers5

689

"%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.

Jerry Coffin
  • 437,173
  • 71
  • 570
  • 1,035
  • 8
    Note that `g++` rejects `%lf` when compiling with `-Wall -Werror -pedantic`: `error: ISO C++ does not support the ‘%lf’ gnu_printf format` – kynan Jun 10 '13 at 12:16
  • 2
    @kynan: If so (at leas assuming a current version of g++), that's a bug in g++. For C89/90 and C++98/03, allowing `l` was an extension. The C99/11 and C++11 standards require the implementation to allow it. – Jerry Coffin Jun 10 '13 at 13:16
  • Seems only g++ 4.7 chokes on it, it works on 4.6. It's triggered by the format warning i.e. `-Wno-format` is enough to make it compile. – kynan Jun 10 '13 at 14:46
  • 1
    Curiously, `scanf` *does* want `double`s represented by `%lf`: it complains that it expected `float *` and found `double *` with just `%f`. – Eric Dand Nov 14 '14 at 07:23
  • 1
    @JerryCoffin g++ still defaults to g++98 mode – M.M Jul 19 '15 at 00:33
  • 7
    @EricDand That's because `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. – TripeHound Aug 26 '15 at 13:58
  • 1
    Two reasons for upvote, 1) good answer. 2) score value was previously sitting on an ugly value. – ryyker Feb 19 '21 at 14:02
63

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.
user694733
  • 13,861
  • 1
  • 40
  • 62
mloskot
  • 33,165
  • 10
  • 97
  • 122
27

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.

ti7
  • 7,285
  • 3
  • 25
  • 49
vitaut
  • 37,224
  • 19
  • 144
  • 248
  • 1
    -1: `l` (lowercase) modifier is for integer types (http://www.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`. – user470379 Jan 19 '11 at 19:28
  • 10
    user470379: So where is the contradiction with my answer? Haven't I said that `l` is not required in `printf` for `double`. – vitaut Jan 20 '11 at 10:09
16

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.

AnT
  • 291,388
  • 39
  • 487
  • 734
11

%Lf (note the capital L) is the format specifier for long doubles.

For plain doubles, either %e, %E, %f, %g or %G will do.

Frédéric Hamidi
  • 240,249
  • 39
  • 455
  • 462