printf and long double

CGccPrintfLong Double

C Problem Overview


I am using the latest gcc with Netbeans on Windows. Why doesn't long double work? Is the printf specifier %lf wrong?

Code:

#include <stdio.h>

int main(void)
{
    float aboat = 32000.0;
    double abet = 5.32e-5;
    long double dip = 5.32e-5;

    printf("%f can be written %e\n", aboat, aboat);
    printf("%f can be written %e\n", abet, abet);
    printf("%lf can be written %le\n", dip, dip);

    return 0;
}

Output:

32000.000000 can be written 3.200000e+004
0.000053 can be written 5.320000e-005
-1950228512509697500000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000.000000
can be written 2.725000e+002
Press [Enter] to close the terminal ...

C Solutions


Solution 1 - C

Yes -- for long double, you need to use %Lf (i.e., upper-case 'L').

Solution 2 - C

From the printf manpage:

> l (ell) A following integer > conversion corresponds to a long int > or unsigned long int argument, or a > following n conversion corresponds to > a pointer to a long int argument, or a > following c > conversion corresponds to a wint_t argument, or a following s > conversion corresponds to a pointer to > wchar_t argument.

and

> L A following a, A, e, E, f, F, > g, or G conversion corresponds to a > long double argument. (C99 allows > %LF, but SUSv2 does not.)

So, you want %Le , not %le

Edit: Some further investigation seems to indicate that Mingw uses the MSVC/win32 runtime(for stuff like printf) - which maps long double to double. So mixing a compiler (like gcc) that provides a native long double with a runtime that does not seems to .. be a mess.

Solution 3 - C

If you are using MinGW, the problem is that by default, MinGW uses the I/O resp. formatting functions from the Microsoft C runtime, which doesn't support 80 bit floating point numbers (long double == double in Microsoft land).

However, MinGW also comes with a set of alternative implementations that do properly support long doubles. To use them, prefix the function names with __mingw_ (e.g. __mingw_printf). Depending on the nature of your project, you might also want to globally #define printf __mingw_printf or use -D__USE_MINGW_ANSI_STDIO (which enables the MinGW versions of all the printf-family functions).

Solution 4 - C

In addition to the wrong modifier, which port of gcc to Windows? mingw uses the Microsoft C library and I seem to remember that this library has no support for 80bits long double (microsoft C compiler use 64 bits long double for various reasons).

Solution 5 - C

Was having this issue testing long doubles, and alas, I came across a fix! You have to compile your project with -D__USE_MINGW_ANSI_STDIO:

> Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test > $ gcc main.c > > Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test > $ a.exe c=0.000000 > > Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test > $ gcc main.c -D__USE_MINGW_ANSI_STDIO > > Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test > $ a.exe c=42.000000

Code:

Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test
$ cat main.c
#include <stdio.h>

int main(int argc, char **argv)
{
   long double c=42;

   c/3;

   printf("c=%Lf\n",c);

   return 0;
}

Solution 6 - C

In C99 the length modifier for long double seems to be L and not l. man fprintf (or equivalent for windows) should tell you for your particular platform.

Solution 7 - C

As has been said in other answers, the correct conversion specifier is "%Lf".

You might want to turn on the format warning by using -Wformat (or -Wall, which includes -Wformat) in the gcc invocation

$ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$

source.c:5: warning: format "%le" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$

source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 3 has type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$

source.c:5: warning: format "%le" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type $ gcc source.c
$ gcc -Wall source.c
source.c: In function $ gcc source.c
$ gcc -Wall source.c
source.c: In function main:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
:
source.c:5: warning: format "%lf" expects type double, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 2 has type long double
source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$

source.c:5: warning: format "%le" expects type double, but argument 3 has type long double
$
, but argument 3 has type long double
$

$

Solution 8 - C

printf and scanf function in C/C++ uses Microsoft C library and this library has no support for 10 byte long double. So when you are using printf and scanf function in your C/C++ code to print a long double as output and to take some input as a long double, it will always give you wrong result.

If you want to use long double then you have to use " __mingw_printf " and " __mingw_scanf " function instead of printf and scanf. It has support for 10 byte long double.

Or you can define two macro like this : " #define printf __mingw_printf " and " #define scanf __mingw_scanf "

Use standard format for long double : %Lf

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongameboyView Question on Stackoverflow
Solution 1 - CJerry CoffinView Answer on Stackoverflow
Solution 2 - CnosView Answer on Stackoverflow
Solution 3 - CdnadlingerView Answer on Stackoverflow
Solution 4 - CAProgrammerView Answer on Stackoverflow
Solution 5 - CJason HuntleyView Answer on Stackoverflow
Solution 6 - CJens GustedtView Answer on Stackoverflow
Solution 7 - CpmgView Answer on Stackoverflow
Solution 8 - CRupak PaulView Answer on Stackoverflow