source: trunk/libs/newlib/src/newlib/libm/mathfp/sf_atangent.c @ 444

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

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

File size: 2.8 KB
Line 
1
2/* @(#)z_atangentf.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 * Arctangent
11 *
12 * Input:
13 *   x - floating point value
14 *
15 * Output:
16 *   arctangent of x
17 *
18 * Description:
19 *   This routine calculates arctangents.
20 *
21 *****************************************************************/
22
23#include <float.h>
24#include "fdlibm.h"
25#include "zmath.h"
26
27static const float ROOT3 = 1.732050807;
28static const float a[] = { 0.0, 0.523598775, 1.570796326,
29                     1.047197551 };
30static const float q[] = { 0.1412500740e+1 };
31static const float p[] = { -0.4708325141, -0.5090958253e-1 };
32
33float
34atangentf (float x,
35        float v,
36        float u,
37        int arctan2)
38{
39  float f, g, R, P, Q, A, res;
40  int N;
41  int branch = 0;
42  int expv, expu;
43
44  /* Preparation for calculating arctan2. */
45  if (arctan2)
46    {
47      if (u == 0.0)
48        if (v == 0.0)
49          {
50            errno = ERANGE;
51            return (z_notanum_f.f);
52          }
53        else
54          {
55            branch = 1;
56            res = __PI_OVER_TWO;
57          }
58
59      if (!branch)
60        {
61          int e;
62          /* Get the exponent values of the inputs. */
63          g = frexpf (v, &expv);
64          g = frexpf (u, &expu);
65
66          /* See if a divide will overflow. */
67          e = expv - expu;
68          if (e > FLT_MAX_EXP)
69            {
70               branch = 1;
71               res = __PI_OVER_TWO;
72            }
73
74          /* Also check for underflow. */
75          else if (e < FLT_MIN_EXP)
76            {
77               branch = 2;
78               res = 0.0;
79            }
80         }
81    }
82
83  if (!branch)
84    {
85      if (arctan2)
86        f = fabsf (v / u);
87      else
88        f = fabsf (x);
89
90      if (f > 1.0)
91        {
92          f = 1.0 / f;
93          N = 2;
94        }
95      else
96        N = 0;
97
98      if (f > (2.0 - ROOT3))
99        {
100          A = ROOT3 - 1.0;
101          f = (((A * f - 0.5) - 0.5) + f) / (ROOT3 + f);
102          N++;
103        }
104
105      /* Check for values that are too small. */
106      if (-z_rooteps_f < f && f < z_rooteps_f)
107        res = f;
108
109      /* Calculate the Taylor series. */
110      else
111        {
112          g = f * f;
113          P = (p[1] * g + p[0]) * g;
114          Q = g + q[0];
115          R = P / Q;
116
117          res = f + f * R;
118        }
119
120      if (N > 1)
121        res = -res;
122
123      res += a[N];
124    }
125
126  if (arctan2)
127    {
128      if (u < 0.0)
129        res = __PI - res;
130      if (v < 0.0)
131        res = -res;
132    }
133  else if (x < 0.0)
134    {
135      res = -res;
136    }
137
138  return (res);
139}
Note: See TracBrowser for help on using the repository browser.