diff options
Diffstat (limited to 'lib/msun/i387/e_asin.S')
-rw-r--r-- | lib/msun/i387/e_asin.S | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/msun/i387/e_asin.S b/lib/msun/i387/e_asin.S index 5b2a1bd..de031cf 100644 --- a/lib/msun/i387/e_asin.S +++ b/lib/msun/i387/e_asin.S @@ -37,13 +37,19 @@ RCSID("$FreeBSD$") -/* asin = atan (x / sqrt(1 - x^2)) */ +/* + * asin(x) = atan2(x, sqrt(1 - x^2). + * Actually evaluate (1 - x^2) as (1 - x) * (1 + x) to avoid loss of + * precision when |x| is nearly 1. + */ ENTRY(__ieee754_asin) fldl 4(%esp) /* x */ - fst %st(1) - fmul %st(0) /* x^2 */ fld1 - fsubp /* 1 - x^2 */ - fsqrt /* sqrt (1 - x^2) */ + fld %st(0) + fsub %st(2) /* 1 - x */ + fxch %st(1) + fadd %st(2) /* 1 + x */ + fmulp %st(1) /* (1 - x) * (1 + x) */ + fsqrt fpatan ret |