aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2014-04-02 17:41:02 +0000
committerJoseph Myers <joseph@codesourcery.com>2014-04-02 17:41:02 +0000
commita84e78c8b3c4de94b488fdc5321f71feeb99358f (patch)
treeb4e8a63fd2eb10f4598a5af855e6462a9b06767e
parent6f05bafebac30a389807979f8efbb709f84b486f (diff)
downloadglibc-a84e78c8b3c4de94b488fdc5321f71feeb99358f.zip
glibc-a84e78c8b3c4de94b488fdc5321f71feeb99358f.tar.gz
glibc-a84e78c8b3c4de94b488fdc5321f71feeb99358f.tar.bz2
Fix catan, catanh, __ieee754_logf in round-downward mode (bug 16799, bug 16800).
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.
-rw-r--r--ChangeLog16
-rw-r--r--NEWS2
-rw-r--r--math/libm-test.inc8
-rw-r--r--math/s_catan.c6
-rw-r--r--math/s_catanf.c6
-rw-r--r--math/s_catanh.c6
-rw-r--r--math/s_catanhf.c6
-rw-r--r--math/s_catanhl.c6
-rw-r--r--math/s_catanl.c6
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps96
-rw-r--r--sysdeps/ieee754/flt-32/e_logf.c2
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps96
12 files changed, 242 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a51456..7e530ef 100644
--- 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 63e9303..c7114da 100644
--- 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,
diff --git a/math/libm-test.inc b/math/libm-test.inc
index c6279e7..5e6789f 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -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[] =
diff --git a/math/s_catan.c b/math/s_catan.c
index d6552d8..0cfa924 100644
--- a/math/s_catan.c
+++ b/math/s_catan.c
@@ -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)
diff --git a/math/s_catanf.c b/math/s_catanf.c
index 41e419d..b478684 100644
--- a/math/s_catanf.c
+++ b/math/s_catanf.c
@@ -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)
diff --git a/math/s_catanh.c b/math/s_catanh.c
index 2ba1298..7ef9142 100644
--- a/math/s_catanh.c
+++ b/math/s_catanh.c
@@ -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)
diff --git a/math/s_catanhf.c b/math/s_catanhf.c
index 0ee69a5..0e55aff 100644
--- a/math/s_catanhf.c
+++ b/math/s_catanhf.c
@@ -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)
diff --git a/math/s_catanhl.c b/math/s_catanhl.c
index 537bb3e..6410afe 100644
--- a/math/s_catanhl.c
+++ b/math/s_catanhl.c
@@ -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)
diff --git a/math/s_catanl.c b/math/s_catanl.c
index cea9282..dd01d16 100644
--- a/math/s_catanl.c
+++ b/math/s_catanl.c
@@ -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)
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 0252d5b..aea6c51 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -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
diff --git a/sysdeps/ieee754/flt-32/e_logf.c b/sysdeps/ieee754/flt-32/e_logf.c
index 7da6489..cf75e11 100644
--- a/sysdeps/ieee754/flt-32/e_logf.c
+++ b/sysdeps/ieee754/flt-32/e_logf.c
@@ -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 */
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index 1b6ebe2..4ba83a4 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -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