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.
This commit is contained in:
Joseph Myers 2014-04-02 17:41:02 +00:00
parent 6f05bafeba
commit a84e78c8b3
12 changed files with 242 additions and 14 deletions

View File

@ -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.

2
NEWS
View File

@ -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,

View 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[] =

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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

View 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 */

View 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