scanf没有进入长双

min*_*t93 3 c++ mingw

我有扫描函数在下面的代码中读取long double的问题:

(请原谅我可怜的英文)

#include <iostream>
#include <cstdlib>
#include <math.h>
using namespace std;
int main()
    {
    int n;
    scanf("%d",&n);
    long double a,b,c,ha,hb,hc,ma,cosa,r,l,res,area;
    for (int i=0;i<n;i++)
    {
        scanf("%Lf %Lf %Lf %Lf",&a,&ha,&hb,&hc);//this is where the problem lies,
  //i need to read 4 long double a,ha,hb,hc
        printf("%Lf %Lf %Lf %Lf\n",a,ha,hb,hc);//but it returned wrong answer so
  //i used printf to check, ps: the code works with float but not with double or
  //long double
        ha*=3;hb*=3;hc*=3;
        c=(a*ha)/hc; b=(a*ha)/hb;
        ma=sqrt(0.5*b*b+0.5*c*c-0.25*a*a);
        cosa=ha/ma;
        r=(2*ma)/3;
        l=b*(b-sqrt(a*a-hb*hb))/ha;
        res=sqrt(l*l+r*r-2*cosa*l*r);
        area=a*ha/2;
        printf("%.3Lf %.3Lf\n",area,res);
    }
    system("PAUSE");
    return 0;}
}
Run Code Online (Sandbox Code Playgroud)

这是输入:

2
3.0 0.8660254038 0.8660254038 0.8660254038
657.8256599140 151.6154399062 213.5392629932 139.4878846649
Run Code Online (Sandbox Code Playgroud)

以及命令行中显示的内容:

2
3.0 0.8660254038 0.8660254038 0.8660254038
3.000000 -4824911833695204400000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000.000000 284622047019579100000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000.0
00000 0.866025
-2.000 0.000
657.8256599140 151.6154399062 213.5392629932 139.4878846649
657.825660 -0.000000 28969688850499604000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000.000000 213.539263
-2.000 0.000
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

我想知道为什么scanf不会在代码中加入long double以及如何修复它.

提前致谢!

Kei*_*son 12

Dev-c ++使用MinGW,它使用gcc编译器和Microsoft运行时库.不幸的是,那些组件在使用的基础类型上存在分歧long double(我认为64对80或96位).Windows假设long double大小与double; gcc做得long double更大.

这两种选择都是有效的,但这种组合会导致C和C++实现失败.

如果您不需要额外的范围和精度,您可以阅读double并存储到long double.

否则,您可以将自定义字符串写入或借用到long double转换器,或者只使用其他实现.

编辑

更多细节:

Microsoft自己的编译器和运行时库在处理long double为64位时是一致的,大小与double.语言标准允许这种(它要求long double是至少一样宽double,但放在这两个相同的要求),但它似乎奇怪的是,它并没有充分利用的x86的80位浮点硬件.

x86上的gcc long double视为96位(sizeof (long double) == 12).我认为这些比特中只有80个是重要的; 额外的16位用于对齐目的.

MinGW使用gcc作为其编译器,但使用Microsoft的运行时库.对于大多数语言功能,这样可以正常工作,但不匹配long double意味着您可以使用long double 进行计算,但是您无法将长双精度值(或指向它们的指针)传递给运行时库.这是MinGW中的一个错误.

MinGW中有解决方法.您可以__USE_MINGW_ANSI_STDIO通过传递-D__USE_MINGW_ANSI_STDIOgcc命令行或添加一行来定义宏

#define __USE_MINGW_ANSI_STDIO
Run Code Online (Sandbox Code Playgroud)

到您的源文件.(它必须在之前 定义#include <stdio.h>.)一位评论者,paulsm4,说-ansi和-posix选项导致MinGW使用自己的符合库(我没有理由怀疑这一点,但我目前无法证实).或者你可以__mingw_printf()直接打电话.

假设您使用的是Windows,Cygwin可能是一个不错的选择(它使用gcc,但它不使用Microsoft的运行时库).或者你可以在long double内部使用,但是double用于I/O.


xan*_*tos 5

你是一个幸运的人。这不会解决long doubleMinGW 上的一般问题,但我会解释你的问题发生了什么。现在,在遥远的一天,当你能够投票时,我希望你投票。:-) (但我不希望这被标记为正确的响应。这是对您需要的响应,而不是对您所问的响应(标题中的一般问题scanf not taking in long double))。

首先,解决方案:使用float. 用于/ 。%f​ 结果与您网站中作为解决方案给出的结果完全相同。作为旁注,如果您想要使用一些小数,请按照最后一个 printf 中所示进行操作:将在小数分隔符后打印 10 位小数。scanfprintfprintf%.10f

第二:为什么 s 有问题double:res=sqrt()计算平方根。使用floats, l*l+r*r-2*cosa*l*r== 0.0,使用doubles 它是 -1.0781242565371940e-010,所以接近零但为负!所以sqrt(-something)是NaN(不是数字) 的一个特殊值double/float。NaN您可以通过执行以下操作来检查某个数字是否为res != res. 这是因为NaN != NaN(但请注意,旧的 C 标准不能保证这一点,但在 Intel 平台上的许多编译器中都可以做到这一点。http: //www.gnu.org/s/hello/manual/libc/Infinity-and-NaN。 html)。这解释了为什么printf打印出类似的内容-1.#IO。