LDBL_MAX -1.#QNAN0e+000 with MinGW?

G

guiguan

I have tried to run this with both eclipse(CDT)+MinGW and Cygwin+GCC

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

int main()
{
puts("The range of ");
printf("\tlong double is [%Le, %Le]$B"@(B[%Le, %Le]\n", -LDBL_MAX, -
LDBL_MIN, LDBL_MIN, LDBL_MAX);
return EXIT_SUCCESS;
}

but got different results:

* In eclipse(CDT)+MinGW
The range of
long double is [-1.#QNAN0e+000, 3.237810e-319]$B"@(B[6.953674e-310,
0.000000e+000]
* In Cygwin+GCC
The range of
long double is [-1.189731e+4932,
-3.362103e-4932]$B"@(B[3.362103e-4932, 1.189731e+4932]

This is weird, and I googled it, then just found this
http://www.thescripts.com/forum/thread498535.html

The LDBL_MAX of long double is machine-dependent, but why it like this
in same machine? I guess it$B!G(Bs the problem with MinGW. Anyone hv any
idea?
 
M

Martin Ambuhl

The LDBL_MAX of long double is machine-dependent, but why it like this
in same machine? I guess it’s the problem with MinGW. Anyone hv any
idea?

No LDBL_MAX is implementation-dependent. That "implementation" is your
compiler, which may choose LDBL_MAX to be something completely
counter-intuitive if your intuition is based on the machine data
representation.
 
L

Laurel

(e-mail address removed) wrote:

[...]
The LDBL_MAX of long double is machine-dependent, but why it like this
in same machine? I guess it's the problem with MinGW. Anyone hv any
idea?

No LDBL_MAX is implementation-dependent. That "implementation" is your
compiler, which may choose LDBL_MAX to be something completely
counter-intuitive if your intuition is based on the machine data
representation.

ok, got ur idea. thx :)
 
T

Tim Prince

I have tried to run this with both eclipse(CDT)+MinGW and Cygwin+GCC

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

int main()
{
puts("The range of ");
printf("\tlong double is [%Le, %Le]?[%Le, %Le]\n", -LDBL_MAX, -
LDBL_MIN, LDBL_MIN, LDBL_MAX);
return EXIT_SUCCESS;
}

but got different results:

* In eclipse(CDT)+MinGW
The range of
long double is [-1.#QNAN0e+000, 3.237810e-319]?[6.953674e-310,
0.000000e+000]
* In Cygwin+GCC
The range of
long double is [-1.189731e+4932,
-3.362103e-4932]?[3.362103e-4932, 1.189731e+4932]

This is weird, and I googled it, then just found this
http://www.thescripts.com/forum/thread498535.html

The LDBL_MAX of long double is machine-dependent, but why it like this
in same machine? I guess it’s the problem with MinGW. Anyone hv any
idea?
If you run this on a compiler which doesn't support long double in
printf(), results such as these are to be expected.
 
K

Keith Thompson

Tim Prince said:
If you run this on a compiler which doesn't support long double in
printf(), results such as these are to be expected.

What compilers don't support long double in printf()? The long double
type has been standard since C89.

(Actually, printf is part of the library, not part of the compiler;
both are part of the implementation.)
 
J

Jack Klein

I have tried to run this with both eclipse(CDT)+MinGW and Cygwin+GCC

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

int main()
{
puts("The range of ");
printf("\tlong double is [%Le, %Le]?[%Le, %Le]\n", -LDBL_MAX, -
LDBL_MIN, LDBL_MIN, LDBL_MAX);
return EXIT_SUCCESS;
}

but got different results:

* In eclipse(CDT)+MinGW
The range of
long double is [-1.#QNAN0e+000, 3.237810e-319]?[6.953674e-310,
0.000000e+000]
* In Cygwin+GCC
The range of
long double is [-1.189731e+4932,
-3.362103e-4932]?[3.362103e-4932, 1.189731e+4932]

This is weird, and I googled it, then just found this
http://www.thescripts.com/forum/thread498535.html

The LDBL_MAX of long double is machine-dependent, but why it like this
in same machine? I guess it?s the problem with MinGW. Anyone hv any
idea?

There is absolutely nothing at all wrong with MinGW, honest. There
might be something wrong with their documentation, if they don't
explain this, or with your situation if they do document this behavior
but you didn't read the documentation.

Probably the most significant difference between the MinGW and Cygwin
packages of gcc, regardless of what IDE or other process you use to
drive them, is not in the compiler. If you get both packages based on
the same gcc version, the compilers are probably identical, or very
close to it.

Your real problem is that MinGW is like a typical gcc distribution,
basically supplied without libraries and links with the host system's
C library.

gcc happens support the full extended precision 80-bit format of the
Intel math coprocessor/FPU for long double. But Microsoft made a
marketing decision a long, long time ago, and decided not to.

Specifically:

"With the 16-bit Microsoft C/C++ compilers, long doubles are stored as
80- bit (10-byte) data types. Under Windows NT, in order to be
compatible with other non-Intel floating point implementations, the
80-bit long double format is aliased to the 64-bit (8-byte) double
format."

You can read the entire sad article on Microsoft's site, in their own
words here:

http://support.microsoft.com/kb/129209

The wording is gibberish, by the way, the 8-bit format is not
"aliased", whatever that means, to 64-bits. It merely means when you
define an object of long double, they use the same 64-bit format that
they use for ordinary double.

So when you use gcc, which does not limit the performance of the Intel
FPU to help Windows NT take over the world, it passed long double
objects and constants to functions as an 80-bit Intel FPU format
object. But Microsoft's library implementation of printf() expects to
receive a 64-bit Intel format value for either double or long double.

The result is undefined behavior.

Cygwin, on the other hand, comes with its own library that expects the
same format for long double that the compiler uses.

To this day, that decision made many years ago, renders Microsoft's
compilers crippled for some types of scientific and engineering
programming.

I'm not a die hard Microsoft basher, but this was certainly an example
of extreme stupidity on their part. They decided that their goal of
world domination was more important than the need of the programmer to
decide when a program needed the maximum precision that the hardware
could provide.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

jacob navia

Keith said:
What compilers don't support long double in printf()? The long double
type has been standard since C89.

Microsoft

Microsoft doesn't support long double precision, and within its
compiler system it is equal to double precision.

Mingw people, instead of writing a new library as I did for lcc-win,
took the "cheap" way and use Microsoft run time library for
printf and all other functions.

Since gcc internally uses double precision, (they did not change that
to adapt gcc to the run time library) that means that the
compiler generates a printf call passing a real long double
(80 bits) and not a double precision number. This means that
the printf can't suceed.

This is of course not standard, but nobody will complain about that
since gcc is gcc. Only when lcc-win does something as bad as declaring
atof in math.h (what doesn't produce any run time failures in 99.99%
of the programs or more) then hell is raised.
 
J

jacob navia

Jack said:
I'm not a die hard Microsoft basher, but this was certainly an example
of extreme stupidity on their part. They decided that their goal of
world domination was more important than the need of the programmer to
decide when a program needed the maximum precision that the hardware
could provide.


Microsoft is perfectly right to do that since the C standard EXPLICITELY
allows setting long double to double. The error is with gcc/mingw, not
with Microsoft. Mingw uses the run time of Microsoft without adapting
the compiler to the run time library and this is surely not Microsoft's
fault!

If you compile your program with Microsoft it will work correctly since
the compiler generates the right call!
 
J

jacob navia

Richard said:
jacob navia said:



Microsoft's implementation supports the long double type, to the precision
required by the Standard to which it conforms.

<snip>


Yeah

I support bignums provided they do not exceed INT_MAX.

Word games, Word games, and more word games.
 
S

santosh

jacob said:
Microsoft is perfectly right to do that since the C standard
EXPLICITELY allows setting long double to double. The error is with
gcc/mingw, not with Microsoft. Mingw uses the run time of Microsoft
without adapting the compiler to the run time library and this is
surely not Microsoft's fault!

Note that Jack said that this Microsoft decision was stupid, not
erroneous.
 
R

Richard Heathfield

jacob navia said:

Microsoft doesn't support long double precision, and within its
compiler system it is equal to double precision.

Microsoft's implementation supports the long double type, to the precision
required by the Standard to which it conforms.

<snip>
 
F

Flash Gordon

jacob navia wrote, On 01/12/07 09:59:
Microsoft

Microsoft doesn't support long double precision, and within its
compiler system it is equal to double precision.

Microsoft *does* support the long double type, they just, as you say,
make it the same as double. The standard allows this.
Mingw people, instead of writing a new library as I did for lcc-win,
took the "cheap" way and use Microsoft run time library for
printf and all other functions.

Since gcc internally uses double precision, (they did not change that
to adapt gcc to the run time library) that means that the
compiler generates a printf call passing a real long double
(80 bits) and not a double precision number. This means that
the printf can't suceed.

MinGW is broken in this regard and does not conform to the C standard.
This is of course not standard, but nobody will complain about that
since gcc is gcc.

That is because it is not gcc that is the problem, it is MinGW which
takes gcc and uses it in an incorrect manner (i.e. does not ensure that
both gcc end the library use the same format for long double).
Only when lcc-win does something as bad as declaring
atof in math.h (what doesn't produce any run time failures in 99.99%
of the programs or more) then hell is raised.

The difference is that we don't get people defending MinGW where there
is clear evidence of non-conformance, we do get you defending lcc-win
where there is clear evidence of non-conformance.
 
F

Flash Gordon

jacob navia wrote, On 01/12/07 11:07:
Yeah

I support bignums provided they do not exceed INT_MAX.

Do you claim that a compiler that has a 16 bit int does not have an int?
Word games, Word games, and more word games.

No, it is true. Had you stated that Microsoft does not support 80 bit
floating point numbers, or that long double was not 80 bit, or something
similar that would have been another matter. However, in this respect
Microsoft does conform to the C standard.

Before too long I should have the latest MS C compiler so I will be able
to see how that conforms to the C standard.
 
K

Keith Thompson

jacob navia said:
Microsoft

Microsoft doesn't support long double precision, and within its
compiler system it is equal to double precision.

You are mistaken. Your statement above is consistent with a failure
to understand what "long double" means.

The C standard (both C89/C90 and C99) requires a floating-point type
called "long double". The standard does not require "long double" to
have more precision than "double". If Microsoft supports double and
long double with the same precision, then it *does* support "long
double precision", which happens to be the same as "double precision".
(I use these terms in their C sense, not as defined by the IEC 60559
floating-point standard.)

Note that even Annex F doesn't require an implementation that defines
__STDC_IEC_559__ to provide more precision for double than for long
double. Specifically (C99 F.2p1):

The C floating types match the IEC 60559 formats as follows:

-- The float type matches the IEC 60559 single format.

-- The double type matches the IEC 60559 double format.

-- The long double type matches an IEC 60559 extended format,
else a non-IEC 60559 extended format, else the IEC 60559
double format.

It then recommends, but does not require, using an IEC 60559 extended
format for long double. The use of "else" rather than "or" is a bit
odd; I think it's intended to imply an order of preference.
Mingw people, instead of writing a new library as I did for lcc-win,
took the "cheap" way and use Microsoft run time library for
printf and all other functions.

Since gcc internally uses double precision, (they did not change that
to adapt gcc to the run time library) that means that the
compiler generates a printf call passing a real long double
(80 bits) and not a double precision number. This means that
the printf can't suceed.

I believe that's correct.
This is of course not standard, but nobody will complain about that
since gcc is gcc.

Not true; plenty of people have complained about it.

Note that MinGW is an implementation, not just a compiler. It uses
the gcc compiler in combination with the Microsoft runtime library.
Neither the compiler nor the runtime library is buggy by itself;
they're just incompatible with each other. So this isn't a gcc bug,
or a Microsoft bug; it's a MinGW bug.

There are two possible ways to fix this bug. One would be to modify
the gcc compiler so it uses 64-bit long double (in fact, I'd expect
this to be a gcc configuration option). Another would be to modify
the runtime library (perhaps by replacing parts of it with
non-Microsoft code) so it handles the extended long double format used
by gcc. Some people have argued that Microsoft should "fix" its
runtime library, as well as its own compiler (which is not used by
MinGW), to use extended precision for long double. Though Microsoft's
decision to use 64-bit long double is perfectly conforming, the
argument is that using an extended format would be more useful.
Only when lcc-win does something as bad as declaring
atof in math.h (what doesn't produce any run time failures in 99.99%
of the programs or more) then hell is raised.

Why must you drag your own implementation into this discussion? This
is not about you. Stop whining.
 
K

Keith Thompson

jacob navia said:
Microsoft is perfectly right to do that since the C standard EXPLICITELY
allows setting long double to double.

To be precise, the standard allows using the same representation for
long double and double. They're still distinct types.
The error is with gcc/mingw, not
with Microsoft. Mingw uses the run time of Microsoft without adapting
the compiler to the run time library and this is surely not Microsoft's
fault!

The error is in the MinGW implementation. It's an integration bug,
not necessarily a compiler bug or a runtime library bug. It could be
fixed either by changing the compiler or by changing the runtime
library. It's gcc's fault to exactly the same extent that it's
Microsoft's fault. The authors of gcc didn't design their compiler to
be used with Microsoft's runtime library; the authors of Microsoft's
runtime library didn't design it to be used with gcc.

[...]
 
R

RoS

In data Sat, 01 Dec 2007 11:01:52 +0100, jacob navia scrisse:
Microsoft is perfectly right to do that since the C standard EXPLICITELY
allows setting long double to double. The error is with gcc/mingw, not
with Microsoft. Mingw uses the run time of Microsoft without adapting
the compiler to the run time library and this is surely not Microsoft's
fault!

If you compile your program with Microsoft it will work correctly since
the compiler generates the right call!

wrong
there are numbers that are rappresentable with 80bit float
and not rappresentable with 64bit float

if i remember well, if a 64bit float try to rappresent a
80bit float should generate in that conversion an exception
in a x86 cpu (but printf can handle this case returning error)
 
J

jacob navia

RoS said:
In data Sat, 01 Dec 2007 11:01:52 +0100, jacob navia scrisse:


wrong
there are numbers that are rappresentable with 80bit float
and not rappresentable with 64bit float

Yes, but as I said above, Microsoft never uses 80 bits
Please read the message before sending this "wrong" stuff!
if i remember well, if a 64bit float try to rappresent a
80bit float should generate in that conversion an exception
in a x86 cpu (but printf can handle this case returning error)

The CPU is in 64 Bit (double precision), not in 80 bits precision
This setting is used by Microsoft.
 
J

jacob navia

James said:
Sure, but what does that have to do with anything, and what is it you're
saying is "wrong"? If Microsoft C doesn't support any 80bit floating
point types, the issues you raise never come up.

When jacob navia is the sender of some message, it is
IMPERATIVE to reply with

"wrong"

:)
 
J

James Kuyper

RoS said:
In data Sat, 01 Dec 2007 11:01:52 +0100, jacob navia scrisse: ....

wrong
there are numbers that are rappresentable with 80bit float
and not rappresentable with 64bit float

if i remember well, if a 64bit float try to rappresent a
80bit float should generate in that conversion an exception
in a x86 cpu (but printf can handle this case returning error)

Sure, but what does that have to do with anything, and what is it you're
saying is "wrong"? If Microsoft C doesn't support any 80bit floating
point types, the issues you raise never come up.
 
S

santosh

Yes, but as I said above, Microsoft never uses 80 bits
Please read the message before sending this "wrong" stuff!


The CPU is in 64 Bit (double precision), not in 80 bits precision
This setting is used by Microsoft.

Actually the x87 FPU internally supports only the "double extended"
precision 80 bit floating-point type.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top