Correct Format Specifier for Double in Printf

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?
}
2

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

7

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.

2

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.

1

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

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

3
Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest