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

Solutions

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

Tags: C / Floating Point / Printf

Similar questions

Invalid type in argument to printf format specifier and extra argument to printf format specifier
I have been debugging this RTOS code in Coverity and ran into few small errors. The errors are self explanatory as they are format specifier errors. Both of the errors are on the main function. The first error is on the line: Error: Invalid type in argument to printf format specifier (PRINTF_ARGS) invalid_type: Argument result to format specifier %...
Question about scanf() with lf specifier and printf() with lf specifier?
I am learning C and I have the following code: (I am using Dev C4.9, Windows XP SP3) When I run the above program and entered 5.3; the program printed x = 0.000000 Can anyone explain why is that, please? Thanks a lot.
How to write a vfprintf wrapper that adds a prefix to format specifier and passes the new format specifier to vfprintf in C89?
I am trying to write a wrapper around vfprintf function but with the requirement that I want to add a prefix to the format specifier and then pass the new format specifier to vfprintf. Now I don't know how to do this, but I have captured my intention in the following code. You can see in the above code, that I want to prefix "foo: error" to the for...
format specifier inside format specifier to change size of leading zeros
I was thinking to solve my issue that is described in the following and then I ended with a question that I couldn't find an answer for it on Google. Question: Is it possible to use format specifier inside another format specifier in printf()? The issue is with size of leading zeros in printf() in following line of code: Is it possible to use a for...
C float or double in printf format specifier and pow function
First printf() gives output 0.000000 but second printf() gives output 1.000000. Why? Using Codeblocks on Windows 7 64 bit. Using gcc command to compile give me an .exe that outputs 1.000000 for both statements. If I compile pressing F9 on Codeblocks, I get 0.000000 for the first statement and 1.000000 for the second. Finally, if I remove #include &...
Correct printf format specifier for size_t: %zu or %Iu?
I want to print out the value of a size_t variable using printf in C++ using Microsoft Visual Studio 2010 (I want to use printf instead of << in this specific piece of code, so please no answers telling me I should use << instead). According to the post Platform independent size_t Format specifiers in c? the correct platform-independent...

Also ask

We use cookies to deliver the best possible experience on our website. By continuing to use this site, accepting or closing this box, you consent to our use of cookies. To learn more, visit our privacy policy.