From: Joseph Myers Date: Mon, 30 Apr 2012 18:56:39 +0000 (+0000) Subject: Fix x86 acos near 1 (bug 13942). X-Git-Tag: glibc-2.16-tps~522 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=adfbc8ac9e192b6e3007f7a47852df937afa2145;p=platform%2Fupstream%2Fglibc.git Fix x86 acos near 1 (bug 13942). --- diff --git a/ChangeLog b/ChangeLog index f436af4..a13a367 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2012-04-30 Joseph Myers + [BZ #13942] + * sysdeps/i386/fpu/e_acos.S (__ieee754_acos): Calculate 1 - x^2 as + (1 - x) * (1 + x). + * sysdeps/i386/fpu/e_acosl.c (__ieee754_acosl): Likewise. + * sysdeps/i386/fpu/e_asin.S (__ieee754_asin): Likewise. + * math/libm-test.inc (acos_test): Add more tests. + (asin_test): Likewise. + * sysdeps/i386/fpu/libm-test-ulps: Update. + * sysdeps/x86_64/fpu/libm-test-ulps: Likewise. + [BZ #14034] * sysdeps/i386/fpu/e_acos.S (__ieee754_acos): Take absolute value of square root. diff --git a/NEWS b/NEWS index 4481ea4..c9848e6 100644 --- a/NEWS +++ b/NEWS @@ -22,7 +22,7 @@ Version 2.16 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883, 13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921, 13924, 13926, 13927, 13928, 13938, - 13941, 13963, 13967, 13970, 13973, 14027, 14033, 14034 + 13941, 13942, 13963, 13967, 13970, 13973, 14027, 14033, 14034 * ISO C11 support: diff --git a/math/libm-test.inc b/math/libm-test.inc index bedff09..d643bad 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -758,6 +758,18 @@ acos_test (void) TEST_f_f (acos, 0.75L, 0.722734247813415611178377352641333362L); TEST_f_f (acos, 2e-17L, 1.57079632679489659923132169163975144L); TEST_f_f (acos, 0.0625L, 1.50825556499840522843072005474337068L); + TEST_f_f (acos, 0x0.ffffffp0L, 3.4526698471620358760324948263873649728491e-4L); + TEST_f_f (acos, -0x0.ffffffp0L, 3.1412473866050770348750401337968641476999L); +#ifndef TEST_FLOAT + TEST_f_f (acos, 0x0.ffffffff8p0L, 1.5258789062648029736620564947844627548516e-5L); + TEST_f_f (acos, -0x0.ffffffff8p0L, 3.1415773948007305904329067627145550395696L); + TEST_f_f (acos, 0x0.ffffffffffffp0L, 8.4293697021788088529885473244391795127130e-8L); + TEST_f_f (acos, -0x0.ffffffffffffp0L, 3.1415925692960962166745548533940296398054L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_f (acos, 0x0.ffffffffffffffffp0L, 3.2927225399135962333718255320079907245059e-10L); + TEST_f_f (acos, -0x0.ffffffffffffffffp0L, 3.1415926532605209844712837599423203309964L); +#endif END (acos); } @@ -933,6 +945,18 @@ asin_test (void) TEST_f_f (asin, 1.0, M_PI_2l); TEST_f_f (asin, -1.0, -M_PI_2l); TEST_f_f (asin, 0.75L, 0.848062078981481008052944338998418080L); + TEST_f_f (asin, 0x0.ffffffp0L, 1.5704510598101804156437184421571127056013L); + TEST_f_f (asin, -0x0.ffffffp0L, -1.5704510598101804156437184421571127056013L); +#ifndef TEST_FLOAT + TEST_f_f (asin, 0x0.ffffffff8p0L, 1.5707810680058339712015850710748035974710L); + TEST_f_f (asin, -0x0.ffffffff8p0L, -1.5707810680058339712015850710748035974710L); + TEST_f_f (asin, 0x0.ffffffffffffp0L, 1.5707962425011995974432331617542781977068L); + TEST_f_f (asin, -0x0.ffffffffffffp0L, -1.5707962425011995974432331617542781977068L); +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_f (asin, 0x0.ffffffffffffffffp0L, 1.5707963264656243652399620683025688888978L); + TEST_f_f (asin, -0x0.ffffffffffffffffp0L, -1.5707963264656243652399620683025688888978L); +#endif END (asin); } diff --git a/sysdeps/i386/fpu/e_acos.S b/sysdeps/i386/fpu/e_acos.S index d10a054..586c7fc 100644 --- a/sysdeps/i386/fpu/e_acos.S +++ b/sysdeps/i386/fpu/e_acos.S @@ -7,13 +7,15 @@ RCSID("$NetBSD: e_acos.S,v 1.4 1995/05/08 23:44:37 jtc Exp $") -/* acos = atan (sqrt(1 - x^2) / x) */ +/* acos = atan (sqrt((1-x) (1+x)) / x) */ ENTRY(__ieee754_acos) fldl 4(%esp) /* x */ fld %st /* x : x */ - fmul %st(0) /* x^2 : x */ - fld1 /* 1 : x^2 : x */ - fsubp /* 1 - x^2 : x */ + fld1 /* 1 : x : x */ + fsubp /* 1 - x : x */ + fld1 /* 1 : 1 - x : x */ + fadd %st(2) /* 1 + x : 1 - x : x */ + fmulp /* 1 - x^2 : x */ fsqrt /* sqrt (1 - x^2) : x */ fabs fxch %st(1) /* x : sqrt (1 - x^2) */ diff --git a/sysdeps/i386/fpu/e_acosl.c b/sysdeps/i386/fpu/e_acosl.c index d249d5a..ab08931 100644 --- a/sysdeps/i386/fpu/e_acosl.c +++ b/sysdeps/i386/fpu/e_acosl.c @@ -12,11 +12,13 @@ __ieee754_acosl (long double x) { long double res; - /* acosl = atanl (sqrtl(1 - x^2) / x) */ + /* acosl = atanl (sqrtl((1-x) (1+x)) / x) */ asm ( "fld %%st\n" - "fmul %%st(0)\n" /* x^2 */ "fld1\n" - "fsubp\n" /* 1 - x^2 */ + "fsubp\n" + "fld1\n" + "fadd %%st(2)\n" + "fmulp\n" /* 1 - x^2 */ "fsqrt\n" /* sqrtl (1 - x^2) */ "fabs\n" "fxch %%st(1)\n" diff --git a/sysdeps/i386/fpu/e_asin.S b/sysdeps/i386/fpu/e_asin.S index a17e922..9a44cb6 100644 --- a/sysdeps/i386/fpu/e_asin.S +++ b/sysdeps/i386/fpu/e_asin.S @@ -7,13 +7,15 @@ RCSID("$NetBSD: e_asin.S,v 1.4 1995/05/08 23:45:40 jtc Exp $") -/* asin = atan (x / sqrt(1 - x^2)) */ +/* asin = atan (x / sqrt((1-x) (1+x))) */ ENTRY(__ieee754_asin) fldl 4(%esp) /* x */ fld %st - fmul %st(0) /* x^2 */ - fld1 - fsubp /* 1 - x^2 */ + fld1 /* 1 : x : x */ + fsubp /* 1 - x : x */ + fld1 /* 1 : 1 - x : x */ + fadd %st(2) /* 1 + x : 1 - x : x */ + fmulp /* 1 - x^2 */ fsqrt /* sqrt (1 - x^2) */ fpatan ret diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps index fdaff35..a49a69d 100644 --- a/sysdeps/i386/fpu/libm-test-ulps +++ b/sysdeps/i386/fpu/libm-test-ulps @@ -80,6 +80,12 @@ ldouble: 1 Test "asin (-0.5) == -pi/6": ildouble: 1 ldouble: 1 +Test "asin (-0x0.ffffffff8p0) == -1.5707810680058339712015850710748035974710": +ildouble: 1 +ldouble: 1 +Test "asin (-0x0.ffffffp0) == -1.5704510598101804156437184421571127056013": +ildouble: 1 +ldouble: 1 Test "asin (-1.0) == -pi/2": ildouble: 1 ldouble: 1 @@ -89,6 +95,12 @@ ldouble: 1 Test "asin (0.75) == 0.848062078981481008052944338998418080": ildouble: 1 ldouble: 1 +Test "asin (0x0.ffffffff8p0) == 1.5707810680058339712015850710748035974710": +ildouble: 1 +ldouble: 1 +Test "asin (0x0.ffffffp0) == 1.5704510598101804156437184421571127056013": +ildouble: 1 +ldouble: 1 Test "asin (1.0) == pi/2": ildouble: 1 ldouble: 1 diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 5068fe6..9a1e80e 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -55,6 +55,12 @@ ldouble: 1 Test "asin (-0.5) == -pi/6": ildouble: 1 ldouble: 1 +Test "asin (-0x0.ffffffffffffffffp0) == -1.5707963264656243652399620683025688888978": +ildouble: 1 +ldouble: 1 +Test "asin (-0x0.ffffffffffffp0) == -1.5707962425011995974432331617542781977068": +ildouble: 1 +ldouble: 1 Test "asin (-1.0) == -pi/2": ildouble: 1 ldouble: 1 @@ -64,6 +70,12 @@ ldouble: 1 Test "asin (0.75) == 0.848062078981481008052944338998418080": ildouble: 1 ldouble: 1 +Test "asin (0x0.ffffffffffffffffp0) == 1.5707963264656243652399620683025688888978": +ildouble: 1 +ldouble: 1 +Test "asin (0x0.ffffffffffffp0) == 1.5707962425011995974432331617542781977068": +ildouble: 1 +ldouble: 1 Test "asin (1.0) == pi/2": ildouble: 1 ldouble: 1