HUGE() pain in the ...

Steve Kargl sgk@troutmask.apl.washington.edu
Sun Jul 18 00:35:00 GMT 2004


On Sat, Jul 17, 2004 at 06:34:38PM +0100, Paul Brook wrote:
> On Saturday 17 July 2004 18:25, Steve Kargl wrote:
> > I've looked at intermediate values in gfc_conv_mpfr_to_tree() from
> > trans-const.c and those values appear correct.  So, I believe the
> > call to build_real() in gfc_conv_mpfr_to_tree() is mangling the
> > number, but I can't find where build_real() lives.
> 
> build_real is in gcc/tree.c.
> 

Oh what a tangle web we weave :-)

Well, I now know what the problem is.  The MPFR function

    p = mpfr_get_str (NULL, &exp, 10, 0, f, GFC_RND_MODE);

in gfc_conv_mpfr_to_tree() will return "the maximum possible number
of digits giving an exact rounding in the given base BASE with the
direction RND".  For BASE=10 and round to nearest, the maximum number
of decimal digits for REAL(4) and REAL(8) are 6 and 15.

Unfortunately, build_real() eventually calls real_from_string2(),
which uses the include/float.h notion of floating point numbers.
This means that "#define DBL_MAX 1.7976931348623157E+308" is 
used and it contains 17 digits.  Well, mpfr gives 1.79769313486232E+308,
which is obviously larger than DBL_MAX; and hence, we get Inf for 
output.

If we ignore MPFR's idea of the maximum number of digits and
explicit request 8 or 17 digits via

  if (kind == gfc_default_double_kind())
    p = mpfr_get_str (NULL, &exp, 10, 17, f, GFC_RND_MODE);
  else
    p = mpfr_get_str (NULL, &exp, 10, 8, f, GFC_RND_MODE);

then my test program yields

kargl[17] ./huge
huge(s) =  0.34028234E+39  0.34028234E+39
huge(d) = 0.1797693134862316E+309 0.1797693134862316E+309
huge(i1) = 127 127
huge(i2) = 32767 32767
huge(i4) = 2147483647 2147483647
huge(i8) = 9223372036854775807 9223372036854775807

where the 1st column is from the HUGE() intrinsic and
the 2nd column is from definition of the model numbers.

Paul, do you want me to re-roll my massive MPFR diff with
the above change incorporated or can I submit this as a
follow-up patch once the original diff is committed.

-- 
Steve



More information about the Fortran mailing list