https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88074

--- Comment #20 from rguenther at suse dot de <rguenther at suse dot de> ---
On Tue, 20 Nov 2018, joseph at codesourcery dot com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88074
> 
> --- Comment #19 from joseph at codesourcery dot com <joseph at codesourcery 
> dot com> ---
> On Tue, 20 Nov 2018, rguenth at gcc dot gnu.org wrote:
> 
> >                 if (fmt->emin < min_exp)
> >                   min_exp = fmt->emin - fmt->p + 1;
> 
> > so somehow the formula fmt->emin - fmt->p + 1 isn't sufficient (that's
> 
> No, it's sufficient.  long double and float128 have the same emin but 
> different precision; you need to use fmt->emin - fmt->p + 1 < min_exp 
> above, or else you'll get the wrong results if the loop looks at the long 
> double format before float128.

Doh, stupid error indeed.  Still that isn't enough and
real_to_decimal_for_mode ICEs.  min_exp above is now correctly -16493
and the real-value we pass in to real_to_decimal_for_mode has exp
-16493 but the result is zero.  That's possibly because

      /* Nonzero value, possibly overflowing or underflowing.  */
      mpfr_init2 (m, SIGNIFICAND_BITS);
      inexact = mpfr_strtofr (m, str, NULL, 10, GMP_RNDZ);

we return true and the rounding mode is GMP_RNDZ?  Indeed when changing
the above to use GMP_RNDN it works OK.  The whole thing is also a bit
awkward IMHO since we go back and forth in real_from_string, using
mpfr to format a base-10 float to a base-16 float string and then use
real_from_string ...

Anyway, a workaround is to elide the "+ 1" in the emin computation,
giving mpfr an extra bit to offset the rounding issues.  So I'll
re-test and will post a patch following this.

Reply via email to