36 *
37 * For better accuracy, 1-x*x is computed as follows
38 * 1-x*x if x < 0.5,
39 * 2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5.
40 *
41 * Special cases:
42 * if x is NaN, return x itself;
43 * if |x|>1, return NaN with invalid signal.
44 */
45
46 #include "libm.h"
47
48 static const long double zero = 0.0L, small = 1.0e-20L, half = 0.5L, one = 1.0L;
49 #ifndef lint
50 static const long double big = 1.0e+20L;
51 #endif
52
53 long double
54 asinl(long double x) {
55 long double t, w;
56
57 w = fabsl(x);
58 if (isnanl(x))
59 return (x + x);
60 else if (w <= half) {
61 if (w < small) {
62 #ifndef lint
63 volatile long double dummy = w + big;
64 /* inexact if w != 0 */
65 #endif
66 return (x);
67 } else
68 return (atanl(x / sqrtl(one - x * x)));
69 } else if (w < one) {
70 t = one - w;
71 w = t + t;
72 return (atanl(x / sqrtl(w - t * t)));
73 } else if (w == one)
74 return (atan2l(x, zero)); /* asin(+-1) = +- PI/2 */
75 else
76 return (zero / zero); /* |x| > 1: invalid */
77 }
|
36 *
37 * For better accuracy, 1-x*x is computed as follows
38 * 1-x*x if x < 0.5,
39 * 2*(1-|x|)-(1-|x|)*(1-|x|) if x >= 0.5.
40 *
41 * Special cases:
42 * if x is NaN, return x itself;
43 * if |x|>1, return NaN with invalid signal.
44 */
45
46 #include "libm.h"
47
48 static const long double zero = 0.0L, small = 1.0e-20L, half = 0.5L, one = 1.0L;
49 #ifndef lint
50 static const long double big = 1.0e+20L;
51 #endif
52
53 long double
54 asinl(long double x) {
55 long double t, w;
56 volatile long double dummy;
57
58 w = fabsl(x);
59 if (isnanl(x))
60 return (x + x);
61 else if (w <= half) {
62 if (w < small) {
63 #ifndef lint
64 dummy = w + big;
65 /* inexact if w != 0 */
66 #endif
67 return (x);
68 } else
69 return (atanl(x / sqrtl(one - x * x)));
70 } else if (w < one) {
71 t = one - w;
72 w = t + t;
73 return (atanl(x / sqrtl(w - t * t)));
74 } else if (w == one)
75 return (atan2l(x, zero)); /* asin(+-1) = +- PI/2 */
76 else
77 return (zero / zero); /* |x| > 1: invalid */
78 }
|