printf and long double

2019-01-03 09:51发布

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

8条回答
家丑人穷心不美
2楼-- · 2019-01-03 10:26

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.

查看更多
爷的心禁止访问
3楼-- · 2019-01-03 10:31

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).

查看更多
来,给爷笑一个
4楼-- · 2019-01-03 10:31

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 `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`
$
查看更多
Rolldiameter
5楼-- · 2019-01-03 10:34

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.

查看更多
霸刀☆藐视天下
6楼-- · 2019-01-03 10:38

Correct Printf conversation in Java :-

  double pi = Math.PI;

  System.out.format("%f%n", pi);       // -->  "3.141593"
  System.out.format("%.3f%n", pi);     // -->  "3.142"
  System.out.format("%10.3f%n", pi);   // -->  "     3.142"
  System.out.format("%-10.3f%n", pi);  // -->  "3.142"
  System.out.format(Locale.FRANCE,
                    "%-10.4f%n%n", pi); // -->  "3,1416"

  Calendar c = Calendar.getInstance();
  System.out.format("%tB %te, %tY%n", c, c, c); // -->  "May 29, 2006"

  System.out.format("%tl:%tM %tp%n", c, c, c);  // -->  "2:34 am"

  System.out.format("%tD%n", c);    // -->  "05/29/06"
查看更多
乱世女痞
7楼-- · 2019-01-03 10:39

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

查看更多
登录 后发表回答