Listing 6

main()
{
#include "float.h"
    double atof();
    static double x[] = {
        (1 + DBL_EPSILON) * DBL_MIN, DBL_MIN * (FLT_RADIX - DBL_EPSILON), 1e-307,
/* (nextafter(x) -x) cannot underflow from here on */
        DBL_MIN * (FLT_RADIX / DBL_EPSILON - 1),
/* many libraries don't do as well as they should with numbers around DBL_EPSILON */
        DBL_EPSILON / FLT_RADIX * (1 - DBL_EPSILON / FLT_RADIX), DBL_EPSILON * (FLT_RADIX - DBL_EPSILON),
/* lower limit of IEEE standard exact conversion is between next two */
        (1-DBL_EPSILON/FLT_RADIX)*1e-10,1e-10,
        (1-DBL_EPSILON/FLT_RADIX)*.1,.1,
        (1 - DBL_EPSILON / FLT_RADIX) / FLT_RADIX, 1 - DBL_EPSILON / FLT_RADIX,
        1., FLT_RADIX - DBL_EPSILON,
        (1-DBL_EPSILON/FLT_RADIX)*10,10.,
/* range where nextafter(x) = x+1; conversion should always be exact */
        1 / DBL_EPSILON + 1, FLT_RADIX / DBL_EPSILON - 1,
/* %.17g formats should switch from f to e format without error between next two */
        (1-DBL_EPSILON/FLT_RADIX)*1e17,1e17,
/* upper limit of exact conversion without long double table of powers of 10 */
        (1-DBL_EPSILON/FLT_RADIX)*1e32,1e32,
/* upper limit of IEEE standard exact conversion is between next two */
        (1-DBL_EPSILON/FLT_RADIX)*1e44,1e44,1e307,
   DBL_MAX / FLT_RADIX * (1 - DBL_EPSILON / FLT_RADIX), 1e308,DBL_MAX * (1 - DBL_EPSILON / FLT_RADIX)};
   char buf[80], *gcvt();
   int i;
   (void) printf("\tformatted value\t\tdouble conversion error\n");
   for (i = 0; i <= 27; ++i) {
      (void) gcvt(x, 17, buf);
      (void) printf("     %s\t%g\n", buf, atof(buf) - x[i]);
   }
}