aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-04-30 18:56:39 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-04-30 18:56:39 +0000
commitadfbc8ac9e192b6e3007f7a47852df937afa2145 (patch)
tree09a345d547258a55e1d410065f9ca09a1bed480c
parent5ba3cc691c856e5c67a7d4cd4713f20a79f7ba81 (diff)
downloadglibc-adfbc8ac9e192b6e3007f7a47852df937afa2145.zip
glibc-adfbc8ac9e192b6e3007f7a47852df937afa2145.tar.gz
glibc-adfbc8ac9e192b6e3007f7a47852df937afa2145.tar.bz2
Fix x86 acos near 1 (bug 13942).
-rw-r--r--ChangeLog10
-rw-r--r--NEWS2
-rw-r--r--math/libm-test.inc24
-rw-r--r--sysdeps/i386/fpu/e_acos.S10
-rw-r--r--sysdeps/i386/fpu/e_acosl.c8
-rw-r--r--sysdeps/i386/fpu/e_asin.S10
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps12
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps12
8 files changed, 76 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index f436af4..a13a367 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2012-04-30 Joseph Myers <joseph@codesourcery.com>
+ [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