Define LDBL_MAX/MIN on C

2019-02-20 12:19发布

问题:

I'm working with C, I have to do an exercise in which I have to print the value of long double min and long double max.

I used float.h as header, but these two macros (LDBL_MIN/MAX) give me the same value as if it was just a double.

I'm using Visual Studio 2015 and if I hover the mouse on LDBL MIN it says #define LDBL_MIN DBL_MIN. Is that why it prints dbl_min instead of ldbl_min?

How can I fix this problem?

printf("Type: Long Double Value: %lf Min: %e Max: %e Memory:%lu\n", 
    val10, LDBL_MIN, LDBL_MAX, longd_size);

It is a problem because my assignment requires two different values for LDBL and DBL.

回答1:

C does not specify that long double must have a greater precision/range than double.

So even if the implementation treats them as different types, they may have the same implementation, range, precision, min value, max value, etc.

Concerning Visual Studio, MS Long Double helps.

To fix the problem, use another compiler that supports long double with a greater precision/range than double. Perhaps GCC?



回答2:

From this reference on the lfoating point types:

long double - extended precision floating point type. Matches IEEE-754 extended floating-point type if supported, otherwise matches some non-standard extended floating-point type as long as its precision is better than double and range is at least as good as double, otherwise matches the type double. Some x86 and x86_64 implementations use the 80-bit x87 floating point type.

Added emphasis is mine.

What the above quote says is that while a compliant C compiler must have the long double type, it doesn't really have to support it differently than double. Something which is probably the case with the Visual Studio C compiler.



回答3:

Those macros are either broken, or long double is just an alias for double on your system. To test, set a long double to DBL_MAX, multiply by two, then subtract DBL_MAX from it. If the result is finite, then you have extra exponent space in the long double. If not, and long double is bigger than double, the extra bytes could just be padding, or you could have the same exponent space and more precision. So LDBL_MAX's genuine value will be just a smidgen over DBL_MAX.

The easiest way to generate the max is simply to look up the binary representation. However if you want to do it in portable C, you can probe it by repeated multiplications to get the magnitude, then fill out the mantissa by repeatedly adding descending powers of two until you run out of precision.