source: trunk/libs/newlib/src/newlib/libm/mathfp/s_asine.c @ 543

Last change on this file since 543 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 3.8 KB
Line 
1
2/* @(#)z_asine.c 1.0 98/08/13 */
3/******************************************************************
4 * The following routines are coded directly from the algorithms
5 * and coefficients given in "Software Manual for the Elementary
6 * Functions" by William J. Cody, Jr. and William Waite, Prentice
7 * Hall, 1980.
8 ******************************************************************/
9
10/*
11FUNCTION
12        <<asin>>, <<asinf>>, <<acos>>, <<acosf>>, <<asine>>, <<asinef>>---arc sine or cosine
13
14INDEX
15   asin
16INDEX
17   asinf
18INDEX
19   acos
20INDEX
21   acosf
22INDEX
23   asine
24INDEX
25   asinef
26
27SYNOPSIS
28        #include <math.h>
29        double asine(double <[x]>);
30        float asinef(float <[x]>);
31        double asin(double <[x]>);
32        float asinf(float <[x]>);
33        double acos(double <[x]>);
34        float acosf(float <[x]>);
35
36DESCRIPTION
37
38<<asin>> computes the inverse sine or cosine of the argument <[x]>.
39Arguments to <<asin>> and <<acos>> must be in the range @minus{}1 to 1.
40
41<<asinf>> and <<acosf>> are identical to <<asin>> and <<acos>>, other
42than taking and returning floats.
43
44RETURNS
45@ifnottex
46<<asin>> and <<acos>> return values in radians, in the range of -pi/2 to pi/2.
47@end ifnottex
48@tex
49<<asin>> and <<acos>> return values in radians, in the range of $-\pi/2$ to $\pi/2$.
50@end tex
51
52If <[x]> is not in the range @minus{}1 to 1, <<asin>> and <<asinf>>
53return NaN (not a number), set the global variable <<errno>> to
54<<EDOM>>, and issue a <<DOMAIN error>> message.
55
56*/
57
58/******************************************************************
59 * Arcsine
60 *
61 * Input:
62 *   x - floating point value
63 *   acosine - indicates acos calculation
64 *
65 * Output:
66 *   Arcsine of x.
67 *
68 * Description:
69 *   This routine calculates arcsine / arccosine.
70 *
71 *****************************************************************/
72
73#include "fdlibm.h"
74#include "zmath.h"
75
76#ifndef _DOUBLE_IS_32BITS
77
78static const double p[] = { -0.27368494524164255994e+2,
79                             0.57208227877891731407e+2,
80                            -0.39688862997404877339e+2,
81                             0.10152522233806463645e+2,
82                            -0.69674573447350646411 };
83static const double q[] = { -0.16421096714498560795e+3,
84                             0.41714430248260412556e+3,
85                            -0.38186303361750149284e+3,
86                             0.15095270841030604719e+3,
87                            -0.23823859153670238830e+2 };
88static const double a[] = { 0.0, 0.78539816339744830962 };
89static const double b[] = { 1.57079632679489661923, 0.78539816339744830962 };
90
91double
92asine (double x,
93        int acosine)
94{
95  int flag, i;
96  int branch = 0;
97  double g, res, R, P, Q, y;
98
99  /* Check for special values. */
100  i = numtest (x);
101  if (i == NAN || i == INF)
102    {
103      errno = EDOM;
104      if (i == NAN)
105        return (x);
106      else
107        return (z_infinity.d);
108    }
109
110  y = fabs (x);
111  flag = acosine;
112
113  if (y > 0.5)
114    {
115      i = 1 - flag;
116
117      /* Check for range error. */
118      if (y > 1.0)
119        {
120          errno = ERANGE;
121          return (z_notanum.d);
122        }
123
124      g = (1 - y) / 2.0;
125      y = -2 * sqrt (g);
126      branch = 1;
127    }
128  else
129    {
130      i = flag;
131      if (y < z_rooteps)
132        res = y;
133      else
134        g = y * y;
135    }
136
137  if (y >= z_rooteps || branch == 1)
138    {
139      /* Calculate the Taylor series. */
140      P = ((((p[4] * g + p[3]) * g + p[2]) * g + p[1]) * g + p[0]) * g;
141      Q = ((((g + q[4]) * g + q[3]) * g + q[2]) * g + q[1]) * g + q[0];
142      R = P / Q;
143
144      res = y + y * R;
145    }
146
147  /* Calculate asine or acose. */
148  if (flag == 0)
149    {
150      res = (a[i] + res) + a[i];
151      if (x < 0.0)
152        res = -res;
153    }
154  else
155    {
156      if (x < 0.0)
157        res = (b[i] + res) + b[i];
158      else
159        res = (a[i] - res) + a[i];
160    }
161
162  return (res);
163}
164
165#endif /* _DOUBLE_IS_32BITS */
Note: See TracBrowser for help on using the repository browser.