crmf 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -0
- data/crmf.gemspec +102 -1
- data/ext/crlibm-1.0beta5/AUTHORS +2 -0
- data/ext/crlibm-1.0beta5/CMakeLists.txt +154 -0
- data/ext/crlibm-1.0beta5/COPYING +340 -0
- data/ext/crlibm-1.0beta5/COPYING.LIB +504 -0
- data/ext/crlibm-1.0beta5/ChangeLog +125 -0
- data/ext/crlibm-1.0beta5/Makefile.am +134 -0
- data/ext/crlibm-1.0beta5/NEWS +0 -0
- data/ext/crlibm-1.0beta5/README +31 -0
- data/ext/crlibm-1.0beta5/README.DEV +23 -0
- data/ext/crlibm-1.0beta5/README.md +5 -0
- data/ext/crlibm-1.0beta5/TODO +66 -0
- data/ext/crlibm-1.0beta5/VERSION +1 -0
- data/ext/crlibm-1.0beta5/acos-td.c +1195 -0
- data/ext/crlibm-1.0beta5/acos-td.h +629 -0
- data/ext/crlibm-1.0beta5/asin-td.c +1297 -0
- data/ext/crlibm-1.0beta5/asin-td.h +620 -0
- data/ext/crlibm-1.0beta5/asincos.c +4488 -0
- data/ext/crlibm-1.0beta5/asincos.h +575 -0
- data/ext/crlibm-1.0beta5/atan-itanium.c +846 -0
- data/ext/crlibm-1.0beta5/atan-pentium.c +280 -0
- data/ext/crlibm-1.0beta5/atan-pentium.h +343 -0
- data/ext/crlibm-1.0beta5/atan_accurate.c +341 -0
- data/ext/crlibm-1.0beta5/atan_accurate.h +198 -0
- data/ext/crlibm-1.0beta5/atan_fast.c +506 -0
- data/ext/crlibm-1.0beta5/atan_fast.h +680 -0
- data/ext/crlibm-1.0beta5/configure.ac +419 -0
- data/ext/crlibm-1.0beta5/crlibm.h +204 -0
- data/ext/crlibm-1.0beta5/crlibm.spec +42 -0
- data/ext/crlibm-1.0beta5/crlibm_private.c +397 -0
- data/ext/crlibm-1.0beta5/crlibm_private.h +1048 -0
- data/ext/crlibm-1.0beta5/csh_fast.c +721 -0
- data/ext/crlibm-1.0beta5/csh_fast.h +771 -0
- data/ext/crlibm-1.0beta5/double-extended.h +496 -0
- data/ext/crlibm-1.0beta5/exp-itanium.c +723 -0
- data/ext/crlibm-1.0beta5/exp-td-standalone.c +87 -0
- data/ext/crlibm-1.0beta5/exp-td.c +1363 -0
- data/ext/crlibm-1.0beta5/exp-td.h +685 -0
- data/ext/crlibm-1.0beta5/exp_build_coeffs/exp_fast_table.c +125 -0
- data/ext/crlibm-1.0beta5/expm1-standalone.c +119 -0
- data/ext/crlibm-1.0beta5/expm1.c +2515 -0
- data/ext/crlibm-1.0beta5/expm1.h +715 -0
- data/ext/crlibm-1.0beta5/interval.h +238 -0
- data/ext/crlibm-1.0beta5/log-de.c +480 -0
- data/ext/crlibm-1.0beta5/log-de.h +747 -0
- data/ext/crlibm-1.0beta5/log-de2.c +280 -0
- data/ext/crlibm-1.0beta5/log-de2.h +2352 -0
- data/ext/crlibm-1.0beta5/log-td.c +1158 -0
- data/ext/crlibm-1.0beta5/log-td.h +819 -0
- data/ext/crlibm-1.0beta5/log.c +2244 -0
- data/ext/crlibm-1.0beta5/log.h +1592 -0
- data/ext/crlibm-1.0beta5/log10-td.c +906 -0
- data/ext/crlibm-1.0beta5/log10-td.h +823 -0
- data/ext/crlibm-1.0beta5/log1p.c +1295 -0
- data/ext/crlibm-1.0beta5/log2-td.c +1521 -0
- data/ext/crlibm-1.0beta5/log2-td.h +821 -0
- data/ext/crlibm-1.0beta5/log2_accurate.c +330 -0
- data/ext/crlibm-1.0beta5/log2_accurate.h +261 -0
- data/ext/crlibm-1.0beta5/log_accurate.c +133 -0
- data/ext/crlibm-1.0beta5/log_accurate.h +261 -0
- data/ext/crlibm-1.0beta5/log_fast.c +360 -0
- data/ext/crlibm-1.0beta5/log_fast.h +440 -0
- data/ext/crlibm-1.0beta5/pow.c +1396 -0
- data/ext/crlibm-1.0beta5/pow.h +3101 -0
- data/ext/crlibm-1.0beta5/prepare +20 -0
- data/ext/crlibm-1.0beta5/rem_pio2_accurate.c +219 -0
- data/ext/crlibm-1.0beta5/rem_pio2_accurate.h +53 -0
- data/ext/crlibm-1.0beta5/scs_lib/AUTHORS +3 -0
- data/ext/crlibm-1.0beta5/scs_lib/COPYING +504 -0
- data/ext/crlibm-1.0beta5/scs_lib/ChangeLog +16 -0
- data/ext/crlibm-1.0beta5/scs_lib/Doxyfile.dev +939 -0
- data/ext/crlibm-1.0beta5/scs_lib/Doxyfile.user +939 -0
- data/ext/crlibm-1.0beta5/scs_lib/INSTALL +215 -0
- data/ext/crlibm-1.0beta5/scs_lib/Makefile.am +17 -0
- data/ext/crlibm-1.0beta5/scs_lib/NEWS +0 -0
- data/ext/crlibm-1.0beta5/scs_lib/README +9 -0
- data/ext/crlibm-1.0beta5/scs_lib/README.DEV +38 -0
- data/ext/crlibm-1.0beta5/scs_lib/TODO +4 -0
- data/ext/crlibm-1.0beta5/scs_lib/VERSION +1 -0
- data/ext/crlibm-1.0beta5/scs_lib/addition_scs.c +623 -0
- data/ext/crlibm-1.0beta5/scs_lib/division_scs.c +110 -0
- data/ext/crlibm-1.0beta5/scs_lib/double2scs.c +174 -0
- data/ext/crlibm-1.0beta5/scs_lib/main.dox +104 -0
- data/ext/crlibm-1.0beta5/scs_lib/multiplication_scs.c +339 -0
- data/ext/crlibm-1.0beta5/scs_lib/poly_fct.c +112 -0
- data/ext/crlibm-1.0beta5/scs_lib/print_scs.c +73 -0
- data/ext/crlibm-1.0beta5/scs_lib/rand_scs.c +63 -0
- data/ext/crlibm-1.0beta5/scs_lib/scs.h +353 -0
- data/ext/crlibm-1.0beta5/scs_lib/scs2double.c +411 -0
- data/ext/crlibm-1.0beta5/scs_lib/scs2mpf.c +58 -0
- data/ext/crlibm-1.0beta5/scs_lib/scs2mpfr.c +61 -0
- data/ext/crlibm-1.0beta5/scs_lib/scs_private.c +23 -0
- data/ext/crlibm-1.0beta5/scs_lib/scs_private.h +133 -0
- data/ext/crlibm-1.0beta5/scs_lib/wrapper_scs.h +486 -0
- data/ext/crlibm-1.0beta5/scs_lib/zero_scs.c +52 -0
- data/ext/crlibm-1.0beta5/trigo_accurate.c +501 -0
- data/ext/crlibm-1.0beta5/trigo_accurate.h +331 -0
- data/ext/crlibm-1.0beta5/trigo_fast.c +1243 -0
- data/ext/crlibm-1.0beta5/trigo_fast.h +639 -0
- data/ext/crlibm-1.0beta5/trigpi.c +1169 -0
- data/ext/crlibm-1.0beta5/trigpi.h +556 -0
- data/ext/crlibm-1.0beta5/triple-double.c +57 -0
- data/ext/crlibm-1.0beta5/triple-double.h +1380 -0
- data/ext/crmf/crmf.c +16 -16
- data/ext/crmf/extconf.rb +12 -8
- data/lib/crmf/version.rb +1 -1
- data/tests/perf.rb +100 -219
- metadata +104 -3
- data/ext/crlibm-1.0beta4.tar.gz +0 -0
@@ -0,0 +1,506 @@
|
|
1
|
+
/*
|
2
|
+
* Correctly rounded arctangent
|
3
|
+
*
|
4
|
+
* Author : Nicolas Gast (Ecole Normale Superieure), Florent de Dinechin
|
5
|
+
*
|
6
|
+
* This file is part of the crlibm library developed by the Arenaire
|
7
|
+
* project at Ecole Normale Superieure de Lyon
|
8
|
+
*
|
9
|
+
* This program is free software; you can redistribute it and/or modify
|
10
|
+
* it under the terms of the GNU Lesser General Public License as published by
|
11
|
+
* the Free Software Foundation; either version 2 of the License, or
|
12
|
+
* (at your option) any later version.
|
13
|
+
*
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
* GNU General Public License for more details.
|
18
|
+
*
|
19
|
+
* You should have received a copy of the GNU Lesser General Public License
|
20
|
+
* along with this program; if not, write to the Free Software
|
21
|
+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
22
|
+
*/
|
23
|
+
|
24
|
+
#include <stdio.h>
|
25
|
+
#include <stdlib.h>
|
26
|
+
#include "crlibm.h"
|
27
|
+
#include "crlibm_private.h"
|
28
|
+
#include "atan_fast.h"
|
29
|
+
|
30
|
+
extern double scs_atan_rn(double);
|
31
|
+
extern double scs_atan_rd(double);
|
32
|
+
extern double scs_atan_ru(double);
|
33
|
+
extern double scs_atanpi_rn(double);
|
34
|
+
extern double scs_atanpi_rd(double);
|
35
|
+
extern double scs_atanpi_ru(double);
|
36
|
+
|
37
|
+
|
38
|
+
static void atan_quick(double *atanhi,double *atanlo, int *index_of_e, double x) {
|
39
|
+
|
40
|
+
double tmphi,tmplo, x0hi,x0lo;
|
41
|
+
double q,Xred2,x2;
|
42
|
+
double Xredhi,Xredlo;
|
43
|
+
double xmBihi, xmBilo, tmphi2, tmplo2, atanlolo;
|
44
|
+
|
45
|
+
int i;
|
46
|
+
|
47
|
+
if (x > MIN_REDUCTION_NEEDED) /* test if reduction is necessary : */
|
48
|
+
{
|
49
|
+
/*
|
50
|
+
* 1) Argument reduction :
|
51
|
+
*
|
52
|
+
* tan(x) = tan( b(i) ) + tan ( (x-b(i)) / (1+x*b(i)))
|
53
|
+
*
|
54
|
+
* 6.3
|
55
|
+
* we choose 62 b(i) so that (x-b(i)) / (1+x*b(i)) < 2^
|
56
|
+
*/
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
if (x > arctan_table[61][B].d) {
|
61
|
+
i=61;
|
62
|
+
Add12( xmBihi , xmBilo , x , -arctan_table[61][B].d);
|
63
|
+
}
|
64
|
+
else
|
65
|
+
{
|
66
|
+
/* compute i so that a[i] < x < a[i+1] */
|
67
|
+
i=31;
|
68
|
+
if (x < arctan_table[i][A].d) i-= 16;
|
69
|
+
else i+=16;
|
70
|
+
if (x < arctan_table[i][A].d) i-= 8;
|
71
|
+
else i+= 8;
|
72
|
+
if (x < arctan_table[i][A].d) i-= 4;
|
73
|
+
else i+= 4;
|
74
|
+
if (x < arctan_table[i][A].d) i-= 2;
|
75
|
+
else i+= 2;
|
76
|
+
if (x < arctan_table[i][A].d) i-= 1;
|
77
|
+
else i+= 1;
|
78
|
+
if (x < arctan_table[i][A].d) i-= 1;
|
79
|
+
xmBihi = x-arctan_table[i][B].d;
|
80
|
+
xmBilo = 0.0;
|
81
|
+
}
|
82
|
+
|
83
|
+
/* we now compute Xred = ( x-b[i] ) / ( 1 + x*b[i] )
|
84
|
+
*
|
85
|
+
* def : x0 := 1+x*b[i]
|
86
|
+
*
|
87
|
+
* 1st we compute an approximation of y = 1/x0
|
88
|
+
* then we compute a better approx x' = y*(2-x0*y)
|
89
|
+
* we can proove that :
|
90
|
+
* if y = 1/x0*(1+e)
|
91
|
+
* then x' = 1/x0 * (1-e^2)
|
92
|
+
*
|
93
|
+
*/
|
94
|
+
|
95
|
+
Mul12(&tmphi,&tmplo, x, arctan_table[i][B].d);
|
96
|
+
|
97
|
+
if (x > 1)
|
98
|
+
Add22(&x0hi,&x0lo,tmphi,tmplo, 1.0,0.0);
|
99
|
+
else {Add22( &x0hi , &x0lo , 1.0,0.0,tmphi,tmplo);}
|
100
|
+
|
101
|
+
Div22( &Xredhi, &Xredlo, xmBihi , xmBilo , x0hi,x0lo);
|
102
|
+
|
103
|
+
/* Polynomial evaluation :
|
104
|
+
*
|
105
|
+
* 1rt compute Q(x^2) = (1 - x^2/3 + ...)
|
106
|
+
* then P(x) = x * Q(x^2)
|
107
|
+
*
|
108
|
+
*/
|
109
|
+
|
110
|
+
Xred2 = Xredhi*Xredhi;
|
111
|
+
|
112
|
+
q = Xred2*(coef_poly[3]+Xred2*
|
113
|
+
(coef_poly[2]+Xred2*
|
114
|
+
(coef_poly[1]+Xred2*
|
115
|
+
coef_poly[0]))) ;
|
116
|
+
|
117
|
+
/* reconstruction : atan(x) = atan(b[i]) + atan(x) */
|
118
|
+
atanlolo = (Xredlo + arctan_table[i][ATAN_BLO].d);
|
119
|
+
atanlolo += Xredhi*q;
|
120
|
+
Add12( tmphi2, tmplo2, arctan_table[i][ATAN_BHI].d, Xredhi);
|
121
|
+
Add12( *atanhi, *atanlo, tmphi2, (tmplo2+atanlolo));
|
122
|
+
|
123
|
+
if (i<10)
|
124
|
+
*index_of_e = 0;
|
125
|
+
else
|
126
|
+
*index_of_e = 1;
|
127
|
+
}
|
128
|
+
else
|
129
|
+
// no reduction needed
|
130
|
+
{
|
131
|
+
/* Polynomial evaluation :
|
132
|
+
*
|
133
|
+
* 1rt compute Q(x^2) = (1 - x^2/3 + ...)
|
134
|
+
* then P(x) = x * Q(x^2)
|
135
|
+
*
|
136
|
+
*/
|
137
|
+
|
138
|
+
x2 = x*x;
|
139
|
+
q = x2*(coef_poly[3]+x2*
|
140
|
+
(coef_poly[2]+x2*
|
141
|
+
(coef_poly[1]+x2*
|
142
|
+
coef_poly[0]))) ;
|
143
|
+
Add12(*atanhi,*atanlo, x , x*q);
|
144
|
+
|
145
|
+
*index_of_e = 2;
|
146
|
+
}
|
147
|
+
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
extern double atan_rn(double x) {
|
157
|
+
|
158
|
+
double atanhi,atanlo;
|
159
|
+
int index_of_e;
|
160
|
+
double sign;
|
161
|
+
db_number x_db;
|
162
|
+
int absxhi;
|
163
|
+
|
164
|
+
x_db.d = x;
|
165
|
+
absxhi = x_db.i[HI] & 0x7fffffff;
|
166
|
+
|
167
|
+
if(x_db.i[HI] & 0x80000000){
|
168
|
+
x_db.i[HI] = absxhi;
|
169
|
+
sign =-1;
|
170
|
+
}
|
171
|
+
else
|
172
|
+
sign=1;
|
173
|
+
|
174
|
+
/* Filter cases */
|
175
|
+
if ( absxhi >= 0x43500000) /* x >= 2^54 */
|
176
|
+
{
|
177
|
+
if ((absxhi > 0x7ff00000) || ((absxhi == 0x7ff00000) && (x_db.i[LO] != 0)))
|
178
|
+
return x+x; /* NaN */
|
179
|
+
else
|
180
|
+
return sign*HALFPI.d; /* atan(+/-infty) = +/- Pi/2 */
|
181
|
+
}
|
182
|
+
if ( absxhi < 0x3E400000 )
|
183
|
+
return x; /* x<2^-27 then atan(x) =~ x */
|
184
|
+
|
185
|
+
atan_quick(&atanhi, &atanlo,&index_of_e , x_db.d);
|
186
|
+
|
187
|
+
if (atanhi == (atanhi + (atanlo*rncst[index_of_e])))
|
188
|
+
return sign*atanhi;
|
189
|
+
else
|
190
|
+
{
|
191
|
+
/* more accuracy is needed , lauch accurate phase */
|
192
|
+
return sign*scs_atan_rn(x_db.d);
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
extern double atan_rd(double x) {
|
203
|
+
double atanhi,atanlo;
|
204
|
+
int index_of_e;
|
205
|
+
double maxepsilon;
|
206
|
+
db_number x_db;
|
207
|
+
int absxhi;
|
208
|
+
int sign;
|
209
|
+
|
210
|
+
x_db.d = x;
|
211
|
+
absxhi = x_db.i[HI] & 0x7FFFFFFF;
|
212
|
+
|
213
|
+
if(x_db.i[HI] & 0x80000000){
|
214
|
+
x_db.i[HI] = absxhi;
|
215
|
+
sign =-1;
|
216
|
+
}
|
217
|
+
else
|
218
|
+
sign=1;
|
219
|
+
|
220
|
+
/* Filter cases */
|
221
|
+
if ( absxhi >= 0x43500000) /* x >= 2^54 */
|
222
|
+
{
|
223
|
+
if ((absxhi > 0x7ff00000) || ((absxhi == 0x7ff00000) && (x_db.i[LO] != 0)))
|
224
|
+
return x+x; /* NaN */
|
225
|
+
else{
|
226
|
+
if (sign>0)
|
227
|
+
return HALFPI.d;
|
228
|
+
else
|
229
|
+
return -HALFPI_TO_PLUS_INFINITY.d; /* atan(x) = Pi/2 */
|
230
|
+
}
|
231
|
+
}
|
232
|
+
else
|
233
|
+
if ( absxhi < 0x3E400000 )
|
234
|
+
{if (sign>0)
|
235
|
+
{if(x==0)
|
236
|
+
return x;
|
237
|
+
else
|
238
|
+
x_db.l--;
|
239
|
+
return x_db.d;
|
240
|
+
}
|
241
|
+
else
|
242
|
+
return x;
|
243
|
+
}
|
244
|
+
|
245
|
+
atan_quick(&atanhi, &atanlo,&index_of_e, x_db.d);
|
246
|
+
maxepsilon = epsilon[index_of_e];
|
247
|
+
atanhi = sign*atanhi;
|
248
|
+
atanlo = sign*atanlo;
|
249
|
+
|
250
|
+
/* Rounding test to - infinity */
|
251
|
+
|
252
|
+
TEST_AND_RETURN_RD(atanhi, atanlo, maxepsilon);
|
253
|
+
|
254
|
+
/* if the previous block didn't return a value, launch accurate phase */
|
255
|
+
return scs_atan_rd(sign*x_db.d);
|
256
|
+
}
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
|
264
|
+
extern double atan_ru(double x) {
|
265
|
+
double atanhi,atanlo;
|
266
|
+
int index_of_e;
|
267
|
+
int sign;
|
268
|
+
double maxepsilon;
|
269
|
+
db_number x_db;
|
270
|
+
int absxhi;
|
271
|
+
|
272
|
+
x_db.d = x;
|
273
|
+
absxhi = x_db.i[HI] & 0x7FFFFFFF;
|
274
|
+
|
275
|
+
if (x_db.i[HI] & 0x80000000){
|
276
|
+
sign = -1;
|
277
|
+
x_db.i[HI] = absxhi;
|
278
|
+
}
|
279
|
+
else
|
280
|
+
sign = 1;
|
281
|
+
|
282
|
+
|
283
|
+
/* Filter cases */
|
284
|
+
if ( absxhi >= 0x43500000) /* x >= 2^54 */
|
285
|
+
{
|
286
|
+
if ((absxhi > 0x7ff00000) || ((absxhi == 0x7ff00000) && (x_db.i[LO] != 0)))
|
287
|
+
return x+x; /* NaN */
|
288
|
+
else
|
289
|
+
{
|
290
|
+
if (sign>0)
|
291
|
+
return HALFPI_TO_PLUS_INFINITY.d;
|
292
|
+
else
|
293
|
+
return -HALFPI.d; /* atan(x) = Pi/2 */
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
if ( absxhi < 0x3E400000 ){
|
298
|
+
if(x==0)
|
299
|
+
return x;
|
300
|
+
|
301
|
+
if (sign<0) {
|
302
|
+
x_db.l--;
|
303
|
+
return -x_db.d;
|
304
|
+
}
|
305
|
+
else
|
306
|
+
return x;
|
307
|
+
} /* x<2^-27 then atan(x) =~ x */
|
308
|
+
|
309
|
+
atan_quick(&atanhi, &atanlo, &index_of_e, x_db.d);
|
310
|
+
maxepsilon = epsilon[index_of_e];
|
311
|
+
atanhi = sign*atanhi;
|
312
|
+
atanlo = sign*atanlo;
|
313
|
+
|
314
|
+
TEST_AND_RETURN_RU(atanhi, atanlo, maxepsilon);
|
315
|
+
|
316
|
+
/* if the previous block didn't return a value, launch accurate phase */
|
317
|
+
return scs_atan_ru(x);
|
318
|
+
}
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
extern double atan_rz(double x) {
|
325
|
+
if (x>0)
|
326
|
+
return atan_rd(x);
|
327
|
+
else
|
328
|
+
return atan_ru(x);
|
329
|
+
}
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
/*************************************************************
|
335
|
+
*************************************************************
|
336
|
+
* AtanPi *
|
337
|
+
*************************************************************
|
338
|
+
*************************************************************/
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
extern double atanpi_rn(double x) {
|
343
|
+
|
344
|
+
double atanhi,atanlo,atanpihi,atanpilo;
|
345
|
+
int index_of_e;
|
346
|
+
double sign;
|
347
|
+
db_number x_db;
|
348
|
+
int absxhi;
|
349
|
+
|
350
|
+
x_db.d = x;
|
351
|
+
absxhi = x_db.i[HI] & 0x7fffffff;
|
352
|
+
|
353
|
+
if(x_db.i[HI] & 0x80000000){
|
354
|
+
x_db.i[HI] = absxhi;
|
355
|
+
sign =-1;
|
356
|
+
}
|
357
|
+
else
|
358
|
+
sign=1;
|
359
|
+
|
360
|
+
/* Filter cases */
|
361
|
+
if ( absxhi >= 0x43500000) /* x >= 2^54 */
|
362
|
+
{
|
363
|
+
if ((absxhi > 0x7ff00000) || ((absxhi == 0x7ff00000) && (x_db.i[LO] != 0)))
|
364
|
+
return x+x; /* NaN */
|
365
|
+
else
|
366
|
+
return sign*0.5; /* atan(+/-infty) = +/- Pi/2 */
|
367
|
+
}
|
368
|
+
if ( absxhi < 0x3E400000 )
|
369
|
+
return sign*scs_atanpi_rn(x_db.d); /* TODO optim here */
|
370
|
+
|
371
|
+
atan_quick(&atanhi, &atanlo,&index_of_e , x_db.d);
|
372
|
+
Mul22(&atanpihi,&atanpilo, INVPIH, INVPIL, atanhi,atanlo);
|
373
|
+
|
374
|
+
if (atanpihi == (atanpihi + (atanpilo*rncst[index_of_e])))
|
375
|
+
return sign*atanpihi;
|
376
|
+
else
|
377
|
+
/* more accuracy is needed , lauch accurate phase */
|
378
|
+
return sign*scs_atanpi_rn(x_db.d);
|
379
|
+
}
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
|
384
|
+
|
385
|
+
|
386
|
+
|
387
|
+
extern double atanpi_rd(double x) {
|
388
|
+
double atanhi,atanlo,atanpihi,atanpilo;
|
389
|
+
int index_of_e;
|
390
|
+
double maxepsilon;
|
391
|
+
db_number x_db;
|
392
|
+
int absxhi;
|
393
|
+
int sign;
|
394
|
+
|
395
|
+
x_db.d = x;
|
396
|
+
absxhi = x_db.i[HI] & 0x7FFFFFFF;
|
397
|
+
|
398
|
+
if(x_db.i[HI] & 0x80000000){
|
399
|
+
x_db.i[HI] = absxhi;
|
400
|
+
sign =-1;
|
401
|
+
}
|
402
|
+
else
|
403
|
+
sign=1;
|
404
|
+
|
405
|
+
/* Filter cases */
|
406
|
+
if ( absxhi >= 0x43500000) /* x >= 2^54 */
|
407
|
+
{
|
408
|
+
if ((absxhi > 0x7ff00000) || ((absxhi == 0x7ff00000) && (x_db.i[LO] != 0)))
|
409
|
+
return x+x; /* NaN */
|
410
|
+
else{
|
411
|
+
if (sign>0)
|
412
|
+
return 0.5;
|
413
|
+
/* Or should it be 0.4999999999999999444888487687421729788184165954589843750; nextdown(0.5) */
|
414
|
+
else
|
415
|
+
return -0.5; /* atan(infty) = Pi/2 */
|
416
|
+
}
|
417
|
+
}
|
418
|
+
else
|
419
|
+
if ( absxhi < 0x3E400000 ) {
|
420
|
+
if(x==0.0)
|
421
|
+
return x; /* signed */
|
422
|
+
else
|
423
|
+
return scs_atanpi_rd(sign*x_db.d); /* TODO optim here */
|
424
|
+
}
|
425
|
+
atan_quick(&atanhi, &atanlo,&index_of_e, x_db.d);
|
426
|
+
Mul22(&atanpihi,&atanpilo, INVPIH, INVPIL, atanhi,atanlo);
|
427
|
+
maxepsilon = epsilon[index_of_e];
|
428
|
+
atanpihi = sign*atanpihi;
|
429
|
+
atanpilo = sign*atanpilo;
|
430
|
+
|
431
|
+
/* Rounding test to - infinity */
|
432
|
+
|
433
|
+
TEST_AND_RETURN_RD(atanpihi, atanpilo, maxepsilon);
|
434
|
+
|
435
|
+
/* if the previous block didn't return a value, launch accurate phase */
|
436
|
+
return scs_atanpi_rd(sign*x_db.d);
|
437
|
+
}
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
|
444
|
+
|
445
|
+
extern double atanpi_ru(double x) {
|
446
|
+
double atanhi,atanlo,atanpihi,atanpilo;
|
447
|
+
int index_of_e;
|
448
|
+
int sign;
|
449
|
+
double maxepsilon;
|
450
|
+
db_number x_db;
|
451
|
+
int absxhi;
|
452
|
+
|
453
|
+
x_db.d = x;
|
454
|
+
absxhi = x_db.i[HI] & 0x7FFFFFFF;
|
455
|
+
|
456
|
+
if (x_db.i[HI] & 0x80000000){
|
457
|
+
sign = -1;
|
458
|
+
x_db.i[HI] = absxhi;
|
459
|
+
}
|
460
|
+
else
|
461
|
+
sign = 1;
|
462
|
+
|
463
|
+
|
464
|
+
/* Filter cases */
|
465
|
+
if ( absxhi >= 0x43500000) /* x >= 2^54 */
|
466
|
+
{
|
467
|
+
if ((absxhi > 0x7ff00000) || ((absxhi == 0x7ff00000) && (x_db.i[LO] != 0)))
|
468
|
+
return x+x; /* NaN */
|
469
|
+
else
|
470
|
+
{
|
471
|
+
if (sign>0)
|
472
|
+
return 0.5;
|
473
|
+
else
|
474
|
+
return - 0.5;
|
475
|
+
}
|
476
|
+
}
|
477
|
+
|
478
|
+
if ( absxhi < 0x3E400000 ) {
|
479
|
+
if(x==0.0)
|
480
|
+
return x; /* signed */
|
481
|
+
else
|
482
|
+
return scs_atanpi_ru(x);
|
483
|
+
}
|
484
|
+
atan_quick(&atanhi, &atanlo, &index_of_e, x_db.d);
|
485
|
+
Mul22(&atanpihi,&atanpilo, INVPIH, INVPIL, atanhi,atanlo);
|
486
|
+
maxepsilon = epsilon[index_of_e];
|
487
|
+
atanpihi = sign*atanpihi;
|
488
|
+
atanpilo = sign*atanpilo;
|
489
|
+
|
490
|
+
TEST_AND_RETURN_RU(atanpihi, atanpilo, maxepsilon);
|
491
|
+
|
492
|
+
/* if the previous block didn't return a value, launch accurate phase */
|
493
|
+
return scs_atanpi_ru(x);
|
494
|
+
}
|
495
|
+
|
496
|
+
|
497
|
+
|
498
|
+
|
499
|
+
|
500
|
+
extern double atanpi_rz(double x) {
|
501
|
+
if (x>0)
|
502
|
+
return atanpi_rd(x);
|
503
|
+
else
|
504
|
+
return atanpi_ru(x);
|
505
|
+
}
|
506
|
+
|