67

我在 Windows 上使用最新的 gcc 和 Netbeans。为什么不起作用long double?说明printf%lf错了吗?

代码:

#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;
}

输出:

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

8 回答 8

49

从 printf 手册页:

l (ell) 后面的整数转换对应 long int 或 unsigned long int 参数,或者后面的 n 转换对应指向 long int 参数的指针,或者后面的 c 转换对应 wint_t 参数,或者后面的 s 转换对应于指向 wchar_t 参数的指针。

在 a、A、e、E、f、F、g 或 G 转换之后的 LA 对应于 long double 参数。(C99 允许 %LF,但 SUSv2 不允许。)

所以,你想要%Le,而不是%le

编辑:一些进一步的调查似乎表明 Mingw 使用 MSVC/win32 运行时(用于 printf 之类的东西) - 它将 long double 映射到 double。因此,将提供本机 long double 的编译器(如 gcc)与似乎不会一团糟的运行时混合在一起。

于 2010-11-03T16:25:04.133 回答
48

是的——对于long double,您需要使用%Lf(即,大写的“L”)。

于 2010-11-03T16:23:45.080 回答
29

如果您使用的是 MinGW,问题是默认情况下,MinGW 使用 I/O resp。来自 Microsoft C 运行时的格式化函数,它不支持 80 位浮点数(在 Microsoft领域中为long double== )。double

然而,MinGW 还附带了一组替代实现,它们可以正确支持长双精度数。要使用它们,请在函数名称前加上__mingw_(例如__mingw_printf)。根据您项目的性质,您可能还希望全局#define printf __mingw_printf或使用(它启用所有-family 功能-D__USE_MINGW_ANSI_STDIO的 MinGW 版本)。printf

于 2013-02-20T19:16:33.270 回答
18

除了错误的修饰符,gcc的哪个端口到windows?mingw 使用 Microsoft C 库,我似乎记得这个库不支持 80 位长双精度(出于各种原因,微软 C 编译器使用 64 位长双精度)。

于 2010-11-03T16:35:05.390 回答
9

在测试长双打时遇到了这个问题,唉,我遇到了一个修复!您必须使用 -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

代码:

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;
}
于 2013-03-15T20:19:52.997 回答
5

在 C99 中,长度修饰符 forlong double似乎isL和 not lman fprintf(或等效于 Windows)应该告诉你你的特定平台。

于 2010-11-03T16:23:23.993 回答
2

正如在其他答案中所说,正确的转换说明符是"%Lf".

您可能希望通过在 gcc 调用中使用-Wformat(或-Wall,其中包括)打开格式警告-Wformat

$ gcc source.c
$ gcc -Wall source.c
source.c:在函数`main`中:
source.c:5:警告:格式“%lf”需要类型为“double”,但参数 2 的类型为“long double”
source.c:5:警告:格式“%le”需要类型“double”,但参数 3 的类型为“long double”
$
于 2010-11-03T16:34:58.397 回答
1

C/C++ 中的 printf 和 scanf 函数使用 Microsoft C 库,该库不支持 10 字节长的 double。因此,当您在 C/C++ 代码中使用 printf 和 scanf 函数来打印 long double 作为输出并将一些输入作为 long double 时,它​​总是会给您错误的结果。

如果你想使用 long double 那么你必须使用“ __mingw_printf ”和“ __mingw_scanf ”函数而不是 printf 和 scanf。它支持 10 字节长的双精度。

或者你可以像这样定义两个宏:“#define printf __mingw_printf”和“#define scanf __mingw_scanf”

对 long double 使用标准格式:%Lf

于 2019-07-27T07:52:59.673 回答