]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix catan, catanh, __ieee754_logf in round-downward mode (bug 16799, bug 16800).
authorJoseph Myers <joseph@codesourcery.com>
Wed, 2 Apr 2014 17:41:02 +0000 (17:41 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 2 Apr 2014 17:41:02 +0000 (17:41 +0000)
This patch fixes incorrect results from catan and catanh of certain
special inputs in round-downward mode (bug 16799), and incorrect
results of __ieee754_logf (+/-0) in round-downward mode (bug 16800)
that show up through catan/catanh when tested in all rounding modes,
but not directly in the testing for logf because the bug gets hidden
by the wrappers.

Both bugs involve a zero that should be +0 being -0 instead: one
computed as (1-x)*(1+x) in the catan/catanh case, and one as (x-x) in
the logf case.  The fixes ensure positive zero is used.  Testing of
catan and catanh in all rounding modes is duly enabled.

I expect there are various other bugs in special cases in __ieee754_*
functions that are normally hidden by the wrappers but would show up
for testing with -lieee (or in future with -fno-math-errno if we
replace -lieee and _LIB_VERSION with compile-time redirection to new
*_noerrno symbol names).

Tested x86_64 and x86 and ulps updated accordingly.

[BZ #16799]
[BZ #16800]
* math/s_catan.c (__catan): Avoid passing -0 denominator to atan2
with 0 numerator.
* math/s_catanf.c (__catanf): Likewise.
* math/s_catanh.c (__catanh): Likewise.
* math/s_catanhf.c (__catanhf): Likewise.
* math/s_catanhl.c (__catanhl): Likewise.
* math/s_catanl.c (__catanl): Likewise.
* sysdeps/ieee754/flt-32/e_logf.c (__ieee754_logf): Always divide
by positive zero when computing -Inf result.
* math/libm-test.inc (catan_test): Use ALL_RM_TEST.
(catanh_test): Likewise.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

12 files changed:
ChangeLog
NEWS
math/libm-test.inc
math/s_catan.c
math/s_catanf.c
math/s_catanh.c
math/s_catanhf.c
math/s_catanhl.c
math/s_catanl.c
sysdeps/i386/fpu/libm-test-ulps
sysdeps/ieee754/flt-32/e_logf.c
sysdeps/x86_64/fpu/libm-test-ulps

index 4a514563b29e23c85351b500129b26db4138ceed..7e530ef40d1cf10ea80a1989b78cc41b2726deda 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2014-04-02  Joseph Myers  <joseph@codesourcery.com>
 
+       [BZ #16799]
+       [BZ #16800]
+       * math/s_catan.c (__catan): Avoid passing -0 denominator to atan2
+       with 0 numerator.
+       * math/s_catanf.c (__catanf): Likewise.
+       * math/s_catanh.c (__catanh): Likewise.
+       * math/s_catanhf.c (__catanhf): Likewise.
+       * math/s_catanhl.c (__catanhl): Likewise.
+       * math/s_catanl.c (__catanl): Likewise.
+       * sysdeps/ieee754/flt-32/e_logf.c (__ieee754_logf): Always divide
+       by positive zero when computing -Inf result.
+       * math/libm-test.inc (catan_test): Use ALL_RM_TEST.
+       (catanh_test): Likewise.
+       * sysdeps/i386/fpu/libm-test-ulps: Update.
+       * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
        [BZ #16789]
        * math/s_clog.c (__clog): Use math_force_eval to ensure underflow
        instead of using underflowing value in computing result.
diff --git a/NEWS b/NEWS
index 63e9303df2fc3b4026a2c159dabccbb6e241c282..c7114da7ab5f2945c4d61d72205220c5b8a4f22d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ Version 2.20
   16611, 16613, 16623, 16632, 16634, 16639, 16642, 16648, 16649, 16670,
   16674, 16677, 16680, 16683, 16689, 16695, 16701, 16706, 16707, 16712,
   16713, 16714, 16731, 16739, 16743, 16758, 16759, 16760, 16770, 16786,
-  16789.
+  16789, 16799, 16800.
 
 * Running the testsuite no longer terminates as soon as a test fails.
   Instead, a file tests.sum (xtests.sum from "make xcheck") is generated,
index c6279e75a96a2c5a51fe5b21130db27bf937a078..5e6789f9fbe2a488f2e94f20cf2fb026e3ebc46e 100644 (file)
@@ -5239,9 +5239,7 @@ static const struct test_c_c_data catan_test_data[] =
 static void
 catan_test (void)
 {
-  START (catan, 0);
-  RUN_TEST_LOOP_c_c (catan, catan_test_data, );
-  END_COMPLEX;
+  ALL_RM_TEST (catan, 0, catan_test_data, RUN_TEST_LOOP_c_c, END_COMPLEX);
 }
 
 static const struct test_c_c_data catanh_test_data[] =
@@ -5746,9 +5744,7 @@ static const struct test_c_c_data catanh_test_data[] =
 static void
 catanh_test (void)
 {
-  START (catanh, 0);
-  RUN_TEST_LOOP_c_c (catanh, catanh_test_data, );
-  END_COMPLEX;
+  ALL_RM_TEST (catanh, 0, catanh_test_data, RUN_TEST_LOOP_c_c, END_COMPLEX);
 }
 
 static const struct test_f_f_data cbrt_test_data[] =
index d6552d8b7c3628a0fa51e93e4cb42cad430113fb..0cfa92434af12d349c383b4bd2464e9a3789e5c0 100644 (file)
@@ -89,7 +89,11 @@ __catan (__complex__ double x)
            }
 
          if (absy < DBL_EPSILON / 2.0)
-           den = (1.0 - absx) * (1.0 + absx);
+           {
+             den = (1.0 - absx) * (1.0 + absx);
+             if (den == -0.0)
+               den = 0.0;
+           }
          else if (absx >= 1.0)
            den = (1.0 - absx) * (1.0 + absx) - absy * absy;
          else if (absx >= 0.75 || absy >= 0.5)
index 41e419d8b0bb3927fa0952e40129291129b8d495..b478684652c161d3fd2f2b065f95e377d391035d 100644 (file)
@@ -90,7 +90,11 @@ __catanf (__complex__ float x)
            }
 
          if (absy < FLT_EPSILON / 2.0f)
-           den = (1.0f - absx) * (1.0f + absx);
+           {
+             den = (1.0f - absx) * (1.0f + absx);
+             if (den == -0.0f)
+               den = 0.0f;
+           }
          else if (absx >= 1.0f)
            den = (1.0f - absx) * (1.0f + absx) - absy * absy;
          else if (absx >= 0.75f || absy >= 0.5f)
index 2ba1298bb6e62777a956ec096e3c4cc50b8b52d7..7ef9142b0db6915bd58ddd5a887962ea45c5396f 100644 (file)
@@ -110,7 +110,11 @@ __catanh (__complex__ double x)
            }
 
          if (absy < DBL_EPSILON / 2.0)
-           den = (1.0 - absx) * (1.0 + absx);
+           {
+             den = (1.0 - absx) * (1.0 + absx);
+             if (den == -0.0)
+               den = 0.0;
+           }
          else if (absx >= 1.0)
            den = (1.0 - absx) * (1.0 + absx) - absy * absy;
          else if (absx >= 0.75 || absy >= 0.5)
index 0ee69a5ba07d708fbcfc015ae28e3e0c53477e4c..0e55aff16cb7ec8bbf09a16e739ccda820098da2 100644 (file)
@@ -112,7 +112,11 @@ __catanhf (__complex__ float x)
            }
 
          if (absy < FLT_EPSILON / 2.0f)
-           den = (1.0f - absx) * (1.0f + absx);
+           {
+             den = (1.0f - absx) * (1.0f + absx);
+             if (den == -0.0f)
+               den = 0.0f;
+           }
          else if (absx >= 1.0f)
            den = (1.0f - absx) * (1.0f + absx) - absy * absy;
          else if (absx >= 0.75f || absy >= 0.5f)
index 537bb3e28d55a324b9e9b270e25f8cef6fdadf34..6410afec3101cb3ca016f0c25328cae3350c1e88 100644 (file)
@@ -118,7 +118,11 @@ __catanhl (__complex__ long double x)
            }
 
          if (absy < LDBL_EPSILON / 2.0L)
-           den = (1.0L - absx) * (1.0L + absx);
+           {
+             den = (1.0L - absx) * (1.0L + absx);
+             if (den == -0.0L)
+               den = 0.0L;
+           }
          else if (absx >= 1.0L)
            den = (1.0L - absx) * (1.0L + absx) - absy * absy;
          else if (absx >= 0.75L || absy >= 0.5L)
index cea9282a5458a8adc1755959ea83f260e8067e1d..dd01d16dcda190bd125c17806d56e670738f2753 100644 (file)
@@ -97,7 +97,11 @@ __catanl (__complex__ long double x)
            }
 
          if (absy < LDBL_EPSILON / 2.0L)
-           den = (1.0L - absx) * (1.0L + absx);
+           {
+             den = (1.0L - absx) * (1.0L + absx);
+             if (den == -0.0L)
+               den = 0.0L;
+           }
          else if (absx >= 1.0L)
            den = (1.0L - absx) * (1.0L + absx) - absy * absy;
          else if (absx >= 0.75L || absy >= 0.5L)
index 0252d5bbafc1b2c1493017aa19d876e52fe78b3f..aea6c51b2335c49cac4b035c734b894349b3ce95 100644 (file)
@@ -383,6 +383,54 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: Real part of "catan_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_downward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "catan_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "catan_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
 Function: Real part of "catanh":
 double: 1
 float: 1
@@ -391,6 +439,54 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: Real part of "catanh_downward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
 Function: "cbrt":
 double: 1
 idouble: 1
index 7da64896c1e8836c29fb93f591bd75f5dc16c1a9..cf75e11781e1e533e56bcb936752ea53bbb12e61 100644 (file)
@@ -41,7 +41,7 @@ __ieee754_logf(float x)
        k=0;
        if (ix < 0x00800000) {                  /* x < 2**-126  */
            if (__builtin_expect((ix&0x7fffffff)==0, 0))
-               return -two25/(x-x);            /* log(+-0)=-inf */
+               return -two25/zero;             /* log(+-0)=-inf */
            if (__builtin_expect(ix<0, 0))
                return (x-x)/(x-x);     /* log(-#) = NaN */
            k -= 25; x *= two25; /* subnormal number, scale up x */
index 1b6ebe21ed700becb142052b000627e2fde4bf49..4ba83a46fd4a9a29b4cd011d2bbe1e4d4d1908d9 100644 (file)
@@ -410,6 +410,54 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: Real part of "catan_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "catan_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Real part of "catan_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "catan_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
 Function: Real part of "catanh":
 double: 1
 float: 1
@@ -422,6 +470,54 @@ Function: Imaginary part of "catanh":
 float: 1
 ifloat: 1
 
+Function: Real part of "catanh_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_towardzero":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_towardzero":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh_upward":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
 Function: "cbrt":
 double: 1
 float: 1