Fix csqrt underflow (bugs 14157, 14331)

Andreas Jaeger aj@suse.com
Thu Jul 5 06:02:00 GMT 2012


On 07/04/2012 07:08 PM, Joseph S. Myers wrote:
> csqrt functions raise underflow exceptions inappropriately in some
> cases, as described in bug 14157, and some internal underflows can
> also cause large (in ulps) errors in the results, as described in bug
> 14331.
>
> The following underflow cases suffer at least one of these problems:
>
> * The code for csqrt (0 + small * I) multiplies the imaginary part by
>    0.5, which can cause large errors if it was subnormal.
>
> * csqrt (small + large * I) can cause spurious underflow exceptions
>    scaling down the real part (but no significant error in the return
>    value).  (For csqrt (large + small * I), the imaginary part of the
>    result does indeed underflow, so internal underflows from scaling
>    aren't a problem.)
>
> * In the expressions 0.5 * d + (or -) 0.5 * __real__ x, multiplication
>    by 0.5 may underflow (but because of scaling up, this only loses one
>    bit of precision rather than causing large errors).
>
> * The 0.5 * __imag__ x expression may also underflow, causing large
>    errors for subnormal __imag__ x.
>
> This patch fixes these problems.  Some multiplications by 0.5 are
> moved within expressions so that they only underflow if the final
> result would underflow.  To avoid (d + __real__ x) overflowing in some
> cases, this in turn means that the scaling down for large arguments
> needs to be done for some values that didn't previously need it.  For
> csqrt of pure-imaginary values, sqrt (0.5 * y) is changed to 0.5 *
> sqrt (2.0 * y) where needed to avoid underflow.
>
> Tested x86_64 and x86 and ulps updated accordingly.
>
> 2012-07-04  Joseph Myers  <joseph@codesourcery.com>
>
> 	[BZ #14157]
> 	[BZ #14331]
> 	* math/s_csqrt.c (__csqrt): Avoid multiplying by 0.5 where this
> 	could result in spurious underflow.  Scale down values above
> 	DBL_MAX / 4.0 instead of DBL_MAX / 2.0.
> 	* math/s_csqrtf.c (__csqrtf): Likewise.
> 	* math/s_csqrtl.c (__csqrtl): Likewise.
> 	* math/libm-test.inc (csqrt_test): Add more tests.  Do not allow
> 	spurious underflow.
> 	* sysdeps/i386/fpu/libm-test-ulps: Update.
> 	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

thanks, looks good,

Andreas
-- 
  Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
   SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
    GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
     GPG fingerprint = 93A3 365E CE47 B889 DF7F  FED1 389A 563C C272 A126




More information about the Libc-alpha mailing list