Improve erfc accuracy.

This commit is contained in:
Joseph Myers 2012-03-01 21:15:38 +00:00
parent f775c276fd
commit 7b1902cb3e
8 changed files with 60 additions and 7 deletions

View File

@ -1,3 +1,17 @@
2012-03-01 Joseph Myers <joseph@codesourcery.com>
[BZ #2541]
[BZ #4108]
* sysdeps/ieee754/flt-32/s_erff.c (__erfcf): Mask out one more bit
before squaring exponent.
* sysdeps/ieee754/ldbl-128ibm/s_erfl.c (__erfcl): Mask out whole
bottom long double and 27 bits of top long double before squaring
exponent.
* math/libm-test.inc (erfc_test): Add more tests.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/powerpc/fpu/libm-test-ulps: Likewise.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
2012-03-01 Kai Tietz <ktietz@redhat.com>
* soft-fp/soft-fp.h (_FP_STRUCT_LAYOUT): New macro.

10
NEWS
View File

@ -9,11 +9,11 @@ Version 2.16
* The following bugs are resolved with this release:
174, 350, 411, 2547, 2548, 3335, 3992, 4026, 4596, 4822, 5077, 5461, 5805,
5993, 6884, 6907, 9739, 9902, 10110, 10140, 10210, 11174, 11322, 11365,
11494, 12047, 13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531,
13532, 13533, 13547, 13551, 13552, 13553, 13555, 13559, 13583, 13618,
13637, 13695, 13704, 13706, 13738, 13786
174, 350, 411, 2541, 2547, 2548, 3335, 3992, 4026, 4108, 4596, 4822, 5077,
5461, 5805, 5993, 6884, 6907, 9739, 9902, 10110, 10140, 10210, 11174,
11322, 11365, 11494, 12047, 13058, 13525, 13526, 13527, 13528, 13529,
13530, 13531, 13532, 13533, 13547, 13551, 13552, 13553, 13555, 13559,
13583, 13618, 13637, 13695, 13704, 13706, 13738, 13786
* ISO C11 support:

View File

@ -2478,12 +2478,18 @@ erfc_test (void)
TEST_f_f (erfc, 0.75L, 0.288844366346484868401062165408589223L);
TEST_f_f (erfc, 1.25L, 0.0770998717435417698634765188027188596L);
TEST_f_f (erfc, 2.0L, 0.00467773498104726583793074363274707139L);
TEST_f_f (erfc, 0x1.f7303cp+1L, 2.705500297238986897105236321218861842255e-8L);
TEST_f_f (erfc, 4.125L, 0.542340079956506600531223408575531062e-8L);
TEST_f_f (erfc, 0x1.ffa002p+2L, 1.233585992097580296336099501489175967033e-29L);
TEST_f_f (erfc, 0x1.ffffc8p+2L, 1.122671365033056305522366683719541099329e-29L);
#ifdef TEST_LDOUBLE
/* The result can only be represented in long double. */
# if LDBL_MIN_10_EXP < -319
TEST_f_f (erfc, 27.0L, 0.523704892378925568501606768284954709e-318L);
# endif
# if LDBL_MANT_DIG >= 106
TEST_f_f (erfc, 0x1.ffff56789abcdef0123456789a8p+2L, 1.123161416304655390092138725253789378459e-29L);
# endif
#endif
END (erfc);

View File

@ -422,6 +422,17 @@ idouble: 1
Test "erfc (0.75) == 0.288844366346484868401062165408589223":
float: 1
ifloat: 1
Test "erfc (0x1.f7303cp+1) == 2.705500297238986897105236321218861842255e-8":
double: 1
idouble: 1
ildouble: 1
ldouble: 1
Test "erfc (0x1.ffa002p+2) == 1.233585992097580296336099501489175967033e-29":
ildouble: 1
ldouble: 1
Test "erfc (0x1.ffffc8p+2) == 1.122671365033056305522366683719541099329e-29":
double: 1
idouble: 1
Test "erfc (1.25) == 0.0770998717435417698634765188027188596":
ildouble: 1
ldouble: 1

View File

@ -200,7 +200,7 @@ float __erfcf(float x)
sb5+s*(sb6+s*sb7))))));
}
GET_FLOAT_WORD(ix,x);
SET_FLOAT_WORD(z,ix&0xfffff000);
SET_FLOAT_WORD(z,ix&0xffffe000);
r = __ieee754_expf(-z*z-(float)0.5625)*
__ieee754_expf((z-x)*(z+x)+R/S);
if(hx>0) return r/x; else return two-r/x;

View File

@ -920,7 +920,8 @@ __erfcl (long double x)
}
u.value = x;
u.parts32.w3 = 0;
u.parts32.w2 &= 0xffffe000;
u.parts32.w2 = 0;
u.parts32.w1 &= 0xf8000000;
z = u.value;
r = __ieee754_expl (-z * z - 0.5625) *
__ieee754_expl ((z - x) * (z + x) + p);

View File

@ -422,6 +422,15 @@ idouble: 1
Test "erfc (0.75) == 0.288844366346484868401062165408589223":
float: 1
ifloat: 1
Test "erfc (0x1.f7303cp+1) == 2.705500297238986897105236321218861842255e-8":
double: 1
idouble: 1
Test "erfc (0x1.ffa002p+2) == 1.233585992097580296336099501489175967033e-29":
float: 1
ifloat: 1
Test "erfc (0x1.ffff56789abcdef0123456789a8p+2) == 1.123161416304655390092138725253789378459e-29":
ildouble: 1
ldouble: 1
Test "erfc (2.0) == 0.00467773498104726583793074363274707139":
double: 1
idouble: 1

View File

@ -467,6 +467,16 @@ double: 1
idouble: 1
# erfc
Test "erfc (0x1.f7303cp+1) == 2.705500297238986897105236321218861842255e-8":
double: 1
idouble: 1
ildouble: 1
ldouble: 1
Test "erfc (0x1.ffa002p+2) == 1.233585992097580296336099501489175967033e-29":
float: 1
ifloat: 1
ildouble: 1
ldouble: 1
Test "erfc (1.25) == 0.0770998717435417698634765188027188596":
ildouble: 1
ldouble: 1
@ -1251,7 +1261,9 @@ idouble: 1
Function: "erfc":
double: 1
float: 1
idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1