我有扫描函数在下面的代码中读取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.
你是一个幸运的人。这不会解决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。