Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
280 views
in Technique[技术] by (71.8m points)

c++ - scanf not taking in long double

i have problem with scanf not reading long double in the code below:

(please excuse my poor English)

#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
",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
",area,res);
    }
    system("PAUSE");
    return 0;}
}

here's the input:

2
3.0 0.8660254038 0.8660254038 0.8660254038
657.8256599140 151.6154399062 213.5392629932 139.4878846649

and here what's show in the command line:

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

I want to know why scanf won't take in long double in the code and how to fix it.

Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Dev-c++ uses MinGW, which uses the gcc compiler and the Microsoft runtime library. Unfortunately, those components disagree on the underlying type to be used for long double (64 vs. 80 or 96 bits, I think). Windows assumes long double is the same size as double; gcc makes long double bigger.

Either choice is valid, but the combination results in a broken C and C++ implementation.

If you don't need the extra range and precision, you can read into a double and store into a long double.

Otherwise, you can write or borrow a custom string to long double converter, or just use a different implementation.

EDIT

More details:

Microsoft's own compiler and runtime library are consistent in treating long double as 64 bits, the same size as double. The language standard permits this (it requires long double to be at least as wide as double, but places the same requirements on both), but it does seem odd that it doesn't take advantage of the x86's 80-bit floating-point hardware.

gcc on x86 treats long double as 96 bits (sizeof (long double) == 12). I think only 80 of those bits are significant; the extra 16 bits are for alignment purposes.

MinGW uses gcc as its compiler, but uses Microsoft's runtime library. For most language features, this works fine, but the mismatch for long double means that you can do computations with long double, but you can't pass long double values (or pointers to them) to the runtime library. It's a bug in MinGW.

There are workarounds within MinGW. You can define the macro __USE_MINGW_ANSI_STDIO, either by passing -D__USE_MINGW_ANSI_STDIO on the gcc command line or by adding a line

#define __USE_MINGW_ANSI_STDIO

to your source files. (It has to be defined before #include <stdio.h>.) A commenter, paulsm4, says that the -ansi and -posix options cause MinGW to use its own conforming library (I have no reason to doubt this, but I'm not currently able to confirm it). Or you can call __mingw_printf() directly.

Assuming you're on Windows, Cygwin might be a good alternative (it uses gcc, but it doesn't use Microsoft's runtime library). Or you can use long double internally, but double for I/O.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...