RFA: Fix _DOUBLE_IS_32BITS handling of denormals in dtoa.c

Jeff Johnston jjohnstn@redhat.com
Thu Aug 3 20:39:00 GMT 2006


Patch checked in.  Thanks.

-- Jeff J.

Joern RENNECKE wrote:
> Paranoia fails for sh-elf -m4-single-only with current newlib mainline.
> Paranoia wnts to print the smallest representable floating point number,
> which is a denormal with only the least significant bit set.
> dtoa.c calculates correctly that there is only one bit, but it assumes 
> it has
> to pick it out of a 64 bit double, i.e. it shifts word1, which is always 0,
> left by 31.  Hence converting to floating point yields 0.0, and subtracting
> 31 from the exponent causes an underflow.  Hence we end up with a ds
> that is larger than INT_MAX, and a k of INT_MAX.
> Hence we run out of memory when while calculating
> pow5mult (ptr, S, s5), and the memory gets corrupted when Balloc fails.
> 
> The attached patch fixes this by getting the fraction buts from the 
> right place.
> I've also fixed the rounding of the constant used to compute ds for
> _DOUBLE_IS_32BITS so that we keep the error strictly positive as the
> comment above requires.
> 
> I've sucessfully run a check-gcc check-target-libstdc++-v3 regresion test
> with this patch.
> check-target-newlib already failed for the baseline, see
> http://sourceware.org/ml/newlib/2006/msg00635.html .  I can't investigate
> this now because I have some GCC problems to look into.
> 
> 
> ------------------------------------------------------------------------
> 
> 2006-08-01  J"orn Rennecke  <joern.rennecke@st.com>
> 
> 	* dtoa.c (dtoa_r): Handle the denormalized _DOUBLE_IS_32BITS case
> 	properly.
> 
> --- dtoa.c	2002-02-05 17:14:35.000000000 +0000
> +++ /home/afra/users/renneckej/dtoa.c	2006-08-01 18:49:31.000000000 +0100
> @@ -338,15 +338,23 @@ _DEFUN (_dtoa_r,
>        /* d is denormalized */
>  
>        i = bbits + be + (Bias + (P - 1) - 1);
> +#if defined (_DOUBLE_IS_32BITS)
> +      x = word0 (d) << (32 - i);
> +#else
>        x = (i > 32) ? (word0 (d) << (64 - i)) | (word1 (d) >> (i - 32))
>         : (word1 (d) << (32 - i));
> +#endif
>        d2.d = x;
>        word0 (d2) -= 31 * Exp_msk1;	/* adjust exponent */
>        i -= (Bias + (P - 1) - 1) + 1;
>        denorm = 1;
>      }
>  #endif
> +#if defined (_DOUBLE_IS_32BITS)
> +  ds = (d2.d - 1.5) * 0.289529651 + 0.176091269 + i * 0.30103001;
> +#else
>    ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
> +#endif
>    k = (int) ds;
>    if (ds < 0. && ds != k)
>      k--;			/* want k = floor(ds) */



More information about the Newlib mailing list