Question

For the following code,

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

int main(void) {
    printf("double max = %??\n", DBL_MAX);
    printf("double min = %??\n", DBL_MIN);
    printf("double epsilon  = %??\n", DBL_EPSILON);
    printf("float epsilon  = %??\n", FLT_EPSILON);
    printf("float max = %??\n", FLT_MAX);
    printf("float min = %??\n\n", FLT_MIN);
    return 0;
}

what specifiers would I have to use in place of the ??'s in order for printf to display the various quantities as appropriately-sized decimal numbers?

Was it helpful?

Solution

Use the same format you'd use for any other values of those types:

#include <float.h>
#include <stdio.h>
int main(void) {
    printf("FLT_MAX = %g\n", FLT_MAX);
    printf("DBL_MAX = %g\n", DBL_MAX);
    printf("LDBL_MAX = %Lg\n", LDBL_MAX);
}

Arguments of type float are promoted to double for variadic functions like printf, which is why you use the same format for both.

%f prints a floating-point value using decimal notation with no exponent, which will give you a very long string of (mostly insignificant) digits for very large values.

%e forces the use of an exponent.

%g uses either %f or %e, depending on the magnitude of the number being printed.

On my system, the above prints the following:

FLT_MAX = 3.40282e+38
DBL_MAX = 1.79769e+308
LDBL_MAX = 1.18973e+4932

As Eric Postpischil points out in a comment, the above prints only approximations of the values. You can print more digits by specifying a precision (the number of digits you'll need depends on the precision of the types); for example, you can replace %g by %.20g.

Or, if your implementation supports it, C99 added the ability to print floating-point values in hexadecimal with as much precision as necessary:

printf("FLT_MAX = %a\n", FLT_MAX);
printf("DBL_MAX = %a\n", DBL_MAX);
printf("LDBL_MAX = %La\n", LDBL_MAX);

But the result is not as easily human-readable as the usual decimal format:

FLT_MAX = 0x1.fffffep+127
DBL_MAX = 0x1.fffffffffffffp+1023
LDBL_MAX = 0xf.fffffffffffffffp+16380

(Note: main() is an obsolescent definition; use int main(void) instead.)

OTHER TIPS

To print approximations of the maximums with enough digits to represent the actual values (the result of converting the printed value back to floating-point should be the original value), you can use:

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


int main(void)
{
    printf("%.*g\n", DECIMAL_DIG, FLT_MAX);
    printf("%.*g\n", DECIMAL_DIG, DBL_MAX);
    printf("%.*Lg\n", DECIMAL_DIG, LDBL_MAX);
    return 0;
}

In C 2011, you can use the more specific FLT_DECIMAL_DIG, DBL_DECIMAL_DIG, and LDBL_DECIMAL_DIG in place of DECIMAL_DIG.

To print the exact values, instead of approximations, you need to specify more precision. (int) (log10(x)+1) digits should be enough.

Approximations of the minimums and the epsilons can be printed with sufficient accuracy in the same way. However, calculating the numbers of digits needed for exact values may be more complicated than for the maximums. (Technically, it may be impossible in exotic C implementations. E.g., a base-three floating-point system would have a minimum not representable in any finite number of decimal digits. I am not aware of any such implementations in use.)

You could use the last three prints in my solution to the exercise 2.1 from The C Programming Language

// float or IEEE754 binary32
printf(
    "float: {min: %e, max: %e}, comp: {min: %e, max: %e}\n",
    FLT_MIN, FLT_MAX, pow(2,-126), pow(2,127) * (2 - pow(2,-23))
    );
// double or IEEE754 binary64
printf(
    "double: {min: %e, max: %e}, comp: {min: %e, max: %e}\n",
    DBL_MIN, DBL_MAX, pow(2,-1022), pow(2,1023) * (2 - pow(2,-52))
    );
// long double or IEEE754 binary 128
printf(
    "long double: {min: %Le, max: %Le}, comp: {min: %Le, max: %Le}\n",
    LDBL_MIN, LDBL_MAX, powl(2,-16382), powl(2,16383) * (2 - powl(2,-112))
    );

Obviously, the maximal values are calculated according to IEEE 754. The full solution is available via link: https://github.com/mat90x/tcpl/blob/master/types_ranges.c

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top