C语言中long double的转换说明符

4
long double数据类型在C语言中有以下转换说明符:%Le、%LE、%Lf、%Lg、%LG(参考文献)。我写了一个小程序来测试:
#include <stdio.h>
int main(void) {
  long double d = 656546.67894L;
  printf("%.0Le\n",d);
  printf("%.0LE\n",d);
  printf("%.0Lf\n",d);
  printf("%.0Lg\n",d);
  printf("%.0LG\n",d);
  return 0; 
}

输出结果:

-0

-4E-153

-0

-4e-153

-4E-153

但是都没有给出期望的输出结果,期望的结果是 656547(你可以轻易地理解)。这是什么原因呢?

所使用的编译器是gcc版本3.4.2(mingw-special)。


2
"%.0lf" 对于双精度浮点数的作用是什么?!对于给定的 d,我希望输出为:656547 - whacko__Cracko
1
@dirkgently:你没有理解我的意思,我知道隐式声明可能会引起的问题,我只发布了其中的一部分。 - whacko__Cracko
我正在使用gcc版本3.4.2(mingw-special)进行编译,我知道它有点老了,但我不认为这是问题所在。 - whacko__Cracko
@nthrgeek - 我认为这正是问题所在 - MnGW 3.4.5 在我的电脑上输出了垃圾信息。我的其他编译器(MSVC、Digital Mars和Comeau)则输出了你期望的结果。 - Michael Burr
是的,我刚刚在MSVC中检查过了,那里运行得很好。但为什么在GCC中会出问题呢?我不认为这是实现定义的。是GCC的一个bug吗? - whacko__Cracko
显示剩余6条评论
3个回答

11

从一个旧的mingw wiki得知:

mingw使用微软C运行时库及其实现的printf不支持“long double”类型。作为一种解决方法,您可以将其强制转换为“double”,然后将其传递给printf。例如:

printf("value = %g\n", (double) my_long_double_value);
请注意,'long long'类型也存在类似的问题。使用'I64'(I六十四)长度修饰符代替gcc的'll'(L L)。例如:
printf("value = %I64d\n", my_long_long_value);

编辑(6年后):另外请参考 Keith Thompson 的评论以获取解决方法:

在源文件中添加 #define __USE_MINGW_ANSI_STDIO 1 或将命令行更改为 gcc -D__USE_MINGW_ANSI_STDIO=1


1
我知道这个,不关心四舍五入,但我想知道为什么长双精度会出问题? - whacko__Cracko
好的。我更新了我的回答,以便给你想要的东西 :-) - Gonzalo
2
谢谢,那就是 MinGW 的问题! - whacko__Cracko
2
有一个解决方法:在源文件中添加 #define __USE_MINGW_ANSI_STDIO 1 或者更改命令行为 gcc -D__USE_MINGW_ANSI_STDIO=1 - Keith Thompson
旧版MinGW维基百科的链接已经失效,而且相关页面似乎已经不存在了,所以请等编辑队列清空后,有人能否编辑一个归档链接。我找到的唯一有效的存档网址是https://web.archive.org/web/20090919052257/http://oldwiki.mingw.org/index.php/long%20double。 - AJM

1

MinGW C库由MSVCRT.DLL提供,该库与Windows一起提供,并且实际上是旧的VC++ 6.0库。

然而,MinGW确实使用GNU C++库,尽管它依赖于底层的C库,但它支持使用iostreams输出long double。即使您不打算通常使用C++,只要为了支持这个功能,可能值得使用足够的C++。


不,我使用的mingw特别版不支持long double。我的意思是它给出了与之前相同的错误结果。 - whacko__Cracko

0

使用MinGW-W64,架构为i686(x86-64无法工作)可能是一个解决方案。我尝试了一下,它可以工作。

以下是编译信息:

||=== Build: Debug in TeaErr (compiler: GNU GCC Compiler) ===|
D:\Practice\TeaErr\main.c||In function 'main':|
D:\Practice\TeaErr\main.c|7|warning: unknown conversion type character 'L' in format [-Wformat=]|
D:\Practice\TeaErr\main.c|7|warning: too many arguments for format [-Wformat-extra-args]|
D:\Practice\TeaErr\main.c|7|warning: unknown conversion type character 'L' in format [-Wformat=]|
D:\Practice\TeaErr\main.c|7|warning: too many arguments for format [-Wformat-extra-args]|
D:\Practice\TeaErr\main.c|8|warning: unknown conversion type character 'L' in format [-Wformat=]|
D:\Practice\TeaErr\main.c|8|warning: too many arguments for format [-Wformat-extra-args]|
D:\Practice\TeaErr\main.c|8|warning: unknown conversion type character 'L' in format [-Wformat=]|
D:\Practice\TeaErr\main.c|8|warning: too many arguments for format [-Wformat-extra-args]|
||=== Build finished: 0 error(s), 8 warning(s) (0 minute(s), 1 second(s)) ===|

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    long double a;
    scanf("%Lf",&a);
    printf("%Lf\n",a);
    return 0;
}

结果 安装MinGW-W64时的一些参数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接