1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 |
* |
3 |
* ***** BEGIN LICENSE BLOCK ***** |
4 |
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
5 |
* |
6 |
* The contents of this file are subject to the Mozilla Public License Version |
7 |
* 1.1 (the "License"); you may not use this file except in compliance with |
8 |
* the License. You may obtain a copy of the License at |
9 |
* http://www.mozilla.org/MPL/ |
10 |
* |
11 |
* Software distributed under the License is distributed on an "AS IS" basis, |
12 |
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
13 |
* for the specific language governing rights and limitations under the |
14 |
* License. |
15 |
* |
16 |
* The Original Code is Mozilla Communicator client code, released |
17 |
* March 31, 1998. |
18 |
* |
19 |
* The Initial Developer of the Original Code is |
20 |
* Sun Microsystems, Inc. |
21 |
* Portions created by the Initial Developer are Copyright (C) 1998 |
22 |
* the Initial Developer. All Rights Reserved. |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* Alternatively, the contents of this file may be used under the terms of |
27 |
* either of the GNU General Public License Version 2 or later (the "GPL"), |
28 |
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
29 |
* in which case the provisions of the GPL or the LGPL are applicable instead |
30 |
* of those above. If you wish to allow use of your version of this file only |
31 |
* under the terms of either the GPL or the LGPL, and not to allow others to |
32 |
* use your version of this file under the terms of the MPL, indicate your |
33 |
* decision by deleting the provisions above and replace them with the notice |
34 |
* and other provisions required by the GPL or the LGPL. If you do not delete |
35 |
* the provisions above, a recipient may use your version of this file under |
36 |
* the terms of any one of the MPL, the GPL or the LGPL. |
37 |
* |
38 |
* ***** END LICENSE BLOCK ***** */ |
39 |
|
40 |
/* @(#)s_atan.c 1.3 95/01/18 */ |
41 |
/* |
42 |
* ==================================================== |
43 |
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
44 |
* |
45 |
* Developed at SunSoft, a Sun Microsystems, Inc. business. |
46 |
* Permission to use, copy, modify, and distribute this |
47 |
* software is freely granted, provided that this notice |
48 |
* is preserved. |
49 |
* ==================================================== |
50 |
* |
51 |
*/ |
52 |
|
53 |
/* atan(x) |
54 |
* Method |
55 |
* 1. Reduce x to positive by atan(x) = -atan(-x). |
56 |
* 2. According to the integer k=4t+0.25 chopped, t=x, the argument |
57 |
* is further reduced to one of the following intervals and the |
58 |
* arctangent of t is evaluated by the corresponding formula: |
59 |
* |
60 |
* [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) |
61 |
* [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) |
62 |
* [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) |
63 |
* [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) |
64 |
* [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) |
65 |
* |
66 |
* Constants: |
67 |
* The hexadecimal values are the intended ones for the following |
68 |
* constants. The decimal values may be used, provided that the |
69 |
* compiler will convert from decimal to binary accurately enough |
70 |
* to produce the hexadecimal values shown. |
71 |
*/ |
72 |
|
73 |
#include "fdlibm.h" |
74 |
|
75 |
#ifdef __STDC__ |
76 |
static const double atanhi[] = { |
77 |
#else |
78 |
static double atanhi[] = { |
79 |
#endif |
80 |
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ |
81 |
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ |
82 |
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ |
83 |
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ |
84 |
}; |
85 |
|
86 |
#ifdef __STDC__ |
87 |
static const double atanlo[] = { |
88 |
#else |
89 |
static double atanlo[] = { |
90 |
#endif |
91 |
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ |
92 |
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ |
93 |
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ |
94 |
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ |
95 |
}; |
96 |
|
97 |
#ifdef __STDC__ |
98 |
static const double aT[] = { |
99 |
#else |
100 |
static double aT[] = { |
101 |
#endif |
102 |
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ |
103 |
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ |
104 |
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ |
105 |
-1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ |
106 |
9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ |
107 |
-7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ |
108 |
6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ |
109 |
-5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ |
110 |
4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ |
111 |
-3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ |
112 |
1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ |
113 |
}; |
114 |
|
115 |
#ifdef __STDC__ |
116 |
static const double |
117 |
#else |
118 |
static double |
119 |
#endif |
120 |
one = 1.0, |
121 |
really_big = 1.0e300; |
122 |
|
123 |
#ifdef __STDC__ |
124 |
double fd_atan(double x) |
125 |
#else |
126 |
double fd_atan(x) |
127 |
double x; |
128 |
#endif |
129 |
{ |
130 |
fd_twoints u; |
131 |
double w,s1,s2,z; |
132 |
int ix,hx,id; |
133 |
|
134 |
u.d = x; |
135 |
hx = __HI(u); |
136 |
ix = hx&0x7fffffff; |
137 |
if(ix>=0x44100000) { /* if |x| >= 2^66 */ |
138 |
u.d = x; |
139 |
if(ix>0x7ff00000|| |
140 |
(ix==0x7ff00000&&(__LO(u)!=0))) |
141 |
return x+x; /* NaN */ |
142 |
if(hx>0) return atanhi[3]+atanlo[3]; |
143 |
else return -atanhi[3]-atanlo[3]; |
144 |
} if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ |
145 |
if (ix < 0x3e200000) { /* |x| < 2^-29 */ |
146 |
if(really_big+x>one) return x; /* raise inexact */ |
147 |
} |
148 |
id = -1; |
149 |
} else { |
150 |
x = fd_fabs(x); |
151 |
if (ix < 0x3ff30000) { /* |x| < 1.1875 */ |
152 |
if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ |
153 |
id = 0; x = (2.0*x-one)/(2.0+x); |
154 |
} else { /* 11/16<=|x|< 19/16 */ |
155 |
id = 1; x = (x-one)/(x+one); |
156 |
} |
157 |
} else { |
158 |
if (ix < 0x40038000) { /* |x| < 2.4375 */ |
159 |
id = 2; x = (x-1.5)/(one+1.5*x); |
160 |
} else { /* 2.4375 <= |x| < 2^66 */ |
161 |
id = 3; x = -1.0/x; |
162 |
} |
163 |
}} |
164 |
/* end of argument reduction */ |
165 |
z = x*x; |
166 |
w = z*z; |
167 |
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ |
168 |
s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); |
169 |
s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); |
170 |
if (id<0) return x - x*(s1+s2); |
171 |
else { |
172 |
z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); |
173 |
return (hx<0)? -z:z; |
174 |
} |
175 |
} |