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,1380 @@
|
|
1
|
+
/*
|
2
|
+
* triple_double.h
|
3
|
+
*
|
4
|
+
* This file contains useful tools and data for triple double data representation.
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
|
8
|
+
#ifndef TRIPLE_DOUBLE_H
|
9
|
+
#define TRIPLE_DOUBLE_H 1
|
10
|
+
|
11
|
+
#include "scs_lib/scs.h"
|
12
|
+
#include "scs_lib/scs_private.h"
|
13
|
+
|
14
|
+
/* undef all the variables that might have been defined in
|
15
|
+
scs_lib/scs_private.h */
|
16
|
+
#undef VERSION
|
17
|
+
#undef PACKAGE
|
18
|
+
#undef HAVE_GMP_H
|
19
|
+
#undef HAVE_MPFR_H
|
20
|
+
#undef HAVE_MATHLIB_H
|
21
|
+
/* then include the proper definitions */
|
22
|
+
#include "crlibm_config.h"
|
23
|
+
|
24
|
+
#ifdef HAVE_INTTYPES_H
|
25
|
+
#include <inttypes.h>
|
26
|
+
#endif
|
27
|
+
|
28
|
+
/* Set to O for larger but faster functions.
|
29
|
+
As it only impacts the second step, smaller is preferred */
|
30
|
+
#define TRIPLEDOUBLE_AS_FUNCTIONS 0
|
31
|
+
|
32
|
+
|
33
|
+
#define Renormalize3(resh, resm, resl, ah, am, al) DoRenormalize3(resh, resm, resl, ah, am, al)
|
34
|
+
/*extern void Renormalize3(double* resh, double* resm, double* resl, double ah, double am, double al) ;*/
|
35
|
+
|
36
|
+
#if TRIPLEDOUBLE_AS_FUNCTIONS
|
37
|
+
extern void Mul23(double* resh, double* resm, double* resl, double ah, double al, double bh, double bl);
|
38
|
+
extern void Mul233(double* resh, double* resm, double* resl, double ah, double al, double bh, double bm, double bl);
|
39
|
+
extern void Mul33(double* resh, double* resm, double* resl, double ah, double am, double al, double bh, double bm, double bl);
|
40
|
+
extern void Mul133(double* resh, double* resm, double* resl, double a, double bh, double bm, double bl);
|
41
|
+
extern void Mul123(double* resh, double* resm, double* resl, double a, double bh, double bl);
|
42
|
+
extern void Sqrt13(double* resh, double* resm, double* resl, double x);
|
43
|
+
extern void Recpr33(double* resh, double* resm, double* resl, double dh, double dm, double dl);
|
44
|
+
#else
|
45
|
+
#define Mul23(resh, resm, resl, ah, al, bh, bl) DoMul23(resh, resm, resl, ah, al, bh, bl)
|
46
|
+
#define Mul233(resh, resm, resl, ah, al, bh, bm, bl) DoMul233(resh, resm, resl, ah, al, bh, bm, bl)
|
47
|
+
#define Mul33(resh, resm, resl, ah, am, al, bh, bm, bl) DoMul33(resh, resm, resl, ah, am, al, bh, bm, bl)
|
48
|
+
#define Mul133(resh, resm, resl, a, bh, bm, bl) DoMul133(resh, resm, resl, a, bh, bm, bl)
|
49
|
+
#define Mul123(resh, resm, resl, a, bh, bl) DoMul123(resh, resm, resl, a, bh, bl)
|
50
|
+
#define Sqrt13(resh, resm, resl , x) DoSqrt13(resh, resm, resl , x)
|
51
|
+
#define Recpr33(resh, resm, resl, dh, dm, dl) DoRecpr33(resh, resm, resl, dh, dm, dl)
|
52
|
+
#endif
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
/* Renormalize3
|
57
|
+
|
58
|
+
Procedure for renormalizing a triple double number, i.e.
|
59
|
+
computing exactly an equivalent sum of three non-overlapping
|
60
|
+
double numbers
|
61
|
+
|
62
|
+
|
63
|
+
Arguments: a triple double number ah, am, al
|
64
|
+
|
65
|
+
Results: a triple double number resh, resm, resl
|
66
|
+
|
67
|
+
Preconditions: abs(ah) > abs(am) > abs(al)
|
68
|
+
ah and am are overlapping not more than 51 bits
|
69
|
+
am and al are overlapping not more than 51 bits
|
70
|
+
|
71
|
+
Guarantees: abs(resh) > abs(resm) > abs(resl)
|
72
|
+
resh and resm are non-overlapping
|
73
|
+
resm and resl are non-overlapping
|
74
|
+
resm = round-to-nearest(resm + resl)
|
75
|
+
|
76
|
+
Details: resh, resm and resl are considered to be pointers
|
77
|
+
|
78
|
+
*/
|
79
|
+
#define DoRenormalize3(resh, resm, resl, ah, am, al) \
|
80
|
+
{ \
|
81
|
+
double _t1h, _t1l, _t2l; \
|
82
|
+
\
|
83
|
+
Add12(_t1h, _t1l, (am), (al)); \
|
84
|
+
Add12((*(resh)), _t2l, (ah), (_t1h)); \
|
85
|
+
Add12((*(resm)), (*(resl)), _t2l, _t1l); \
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
/* Mul23
|
90
|
+
|
91
|
+
Procedure for multiplying two double double numbers resulting
|
92
|
+
in a triple double number
|
93
|
+
|
94
|
+
|
95
|
+
Arguments: two double double numbers:
|
96
|
+
ah, al and
|
97
|
+
bh, bl
|
98
|
+
|
99
|
+
Results: a triple double number resh, resm, resl
|
100
|
+
|
101
|
+
Preconditions: abs(ah) > abs(al)
|
102
|
+
ah and al do not overlap
|
103
|
+
ah = round-to-nearest(ah + al)
|
104
|
+
abs(bh) > abs(bl)
|
105
|
+
bh and bl do not overlap
|
106
|
+
bh = round-to-nearest(bh + bl)
|
107
|
+
|
108
|
+
Guarantees: resm and resl are non-overlapping
|
109
|
+
resm = round-to-nearest(resm + resl)
|
110
|
+
abs(resm) <= 2^(-49) * abs(resh)
|
111
|
+
resh+resm+resl = (ah+al) * (bh+bl) * (1 + eps)
|
112
|
+
where
|
113
|
+
abs(eps) <= 2^(-149)
|
114
|
+
|
115
|
+
Details: resh, resm and resl are considered to be pointers
|
116
|
+
*/
|
117
|
+
#define DoMul23(resh, resm, resl, ah, al, bh, bl) \
|
118
|
+
{ \
|
119
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7, _t8, _t9, _t10; \
|
120
|
+
\
|
121
|
+
Mul12((resh),&_t1,(ah),(bh)); \
|
122
|
+
Mul12(&_t2,&_t3,(ah),(bl)); \
|
123
|
+
Mul12(&_t4,&_t5,(al),(bh)); \
|
124
|
+
_t6 = (al) * (bl); \
|
125
|
+
Add22Cond(&_t7,&_t8,_t2,_t3,_t4,_t5); \
|
126
|
+
Add12(_t9,_t10,_t1,_t6); \
|
127
|
+
Add22Cond((resm),(resl),_t7,_t8,_t9,_t10); \
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
/* Mul233
|
133
|
+
|
134
|
+
Procedure for multiplying a double double number by
|
135
|
+
a triple double number resulting in a triple double number
|
136
|
+
|
137
|
+
|
138
|
+
Arguments: a double double number ah, al
|
139
|
+
a triple double number bh, bm, bl
|
140
|
+
|
141
|
+
Results: a triple double number resh, resm, resl
|
142
|
+
|
143
|
+
Preconditions: abs(ah) > abs(al)
|
144
|
+
ah and al do not overlap
|
145
|
+
ah = round-to-nearest(ah + al)
|
146
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
147
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
148
|
+
where
|
149
|
+
b_o >= 2
|
150
|
+
b_u >= 1
|
151
|
+
|
152
|
+
Guarantees: resm and resl are non-overlapping
|
153
|
+
resm = round-to-nearest(resm + resl)
|
154
|
+
abs(resm) <= 2^(\gamma) * abs(resh)
|
155
|
+
where
|
156
|
+
\gamma >= min(48,b_o-4,b_o+b_u-4)
|
157
|
+
resh+resm+resl=(ah+al) * (bh+bm+bl) * (1+eps)
|
158
|
+
where
|
159
|
+
abs(eps) <=
|
160
|
+
(2^(-99-b_o) + 2^(-99-b_o-b_u) + 2^(-152)) /
|
161
|
+
(1 - 2^(-53) - 2^(-b_o+1) - 2^(-b_o-b_u+1))
|
162
|
+
|
163
|
+
Details: resh, resm and resl are considered to be pointers
|
164
|
+
*/
|
165
|
+
#define DoMul233(resh, resm, resl, ah, al, bh, bm, bl) \
|
166
|
+
{ \
|
167
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7, _t8, _t9, _t10; \
|
168
|
+
double _t11, _t12, _t13, _t14, _t15, _t16, _t17, _t18; \
|
169
|
+
\
|
170
|
+
Mul12((resh),&_t1,(ah),(bh)); \
|
171
|
+
Mul12(&_t2,&_t3,(ah),(bm)); \
|
172
|
+
Mul12(&_t4,&_t5,(ah),(bl)); \
|
173
|
+
Mul12(&_t6,&_t7,(al),(bh)); \
|
174
|
+
Mul12(&_t8,&_t9,(al),(bm)); \
|
175
|
+
_t10 = (al) * (bl); \
|
176
|
+
Add22Cond(&_t11,&_t12,_t2,_t3,_t4,_t5); \
|
177
|
+
Add22Cond(&_t13,&_t14,_t6,_t7,_t8,_t9); \
|
178
|
+
Add22Cond(&_t15,&_t16,_t11,_t12,_t13,_t14); \
|
179
|
+
Add12Cond(_t17,_t18,_t1,_t10); \
|
180
|
+
Add22Cond((resm),(resl),_t17,_t18,_t15,_t16); \
|
181
|
+
}
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
/* Add33
|
187
|
+
|
188
|
+
Procedure for adding two triple double numbers resulting
|
189
|
+
in a triple double number
|
190
|
+
|
191
|
+
|
192
|
+
Arguments: two triple double numbers:
|
193
|
+
ah, am, al and
|
194
|
+
bh, bm, bl
|
195
|
+
|
196
|
+
Results: a triple double number resh, resm, resl
|
197
|
+
|
198
|
+
Preconditions: abs(bh) <= 0.75 * abs(ah) OR ( sign(bh) = sign(ah) AND abs(bh) <= abs(ah)) (i)
|
199
|
+
abs(am) <= 2^(-a_o) * abs(ah)
|
200
|
+
abs(al) <= 2^(-a_u) * abs(am)
|
201
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
202
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
203
|
+
where
|
204
|
+
b_o >= a_o >= 4
|
205
|
+
b_u >= a_u >= 4
|
206
|
+
|
207
|
+
Condition (i) may not be respected if
|
208
|
+
one can assume in this case that ah=am=al=0
|
209
|
+
|
210
|
+
Guarantees: resm and resl are non-overlapping
|
211
|
+
resm = round-to-nearest(resm + resl)
|
212
|
+
abs(resm) <= 2^(-min(a_o,b_o) + 5) * abs(resh)
|
213
|
+
resh+resm+resl = (ah+am+al + bh+bm+bl) * (1+eps)
|
214
|
+
where
|
215
|
+
abs(eps) <= 2^(-min(a_o+a_u,b_o+b_u)-47) + 2^(-min(a_o,a_u)-98)
|
216
|
+
|
217
|
+
Details: resh, resm and resl are considered to be pointers
|
218
|
+
*/
|
219
|
+
|
220
|
+
#define Add33(resh, resm, resl, ah, am, al, bh, bm, bl) \
|
221
|
+
{ \
|
222
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7, _t8; \
|
223
|
+
\
|
224
|
+
Add12((*(resh)),_t1,(ah),(bh)); \
|
225
|
+
Add12Cond(_t2,_t3,(am),(bm)); \
|
226
|
+
_t6 = (al) + (bl); \
|
227
|
+
Add12Cond(_t7,_t4,_t1,_t2); \
|
228
|
+
_t5 = _t3 + _t4; \
|
229
|
+
_t8 = _t5 + _t6; \
|
230
|
+
Add12Cond((*(resm)),(*(resl)),_t7,_t8); \
|
231
|
+
}
|
232
|
+
|
233
|
+
/* Add33Cond
|
234
|
+
|
235
|
+
Procedure for adding two triple double numbers resulting
|
236
|
+
in a triple double number
|
237
|
+
|
238
|
+
|
239
|
+
Arguments: two triple double numbers:
|
240
|
+
ah, am, al and
|
241
|
+
bh, bm, bl
|
242
|
+
|
243
|
+
Results: a triple double number resh, resm, resl
|
244
|
+
|
245
|
+
Preconditions: abs(am) <= 2^(-a_o) * abs(ah)
|
246
|
+
abs(al) <= 2^(-a_u) * abs(am)
|
247
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
248
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
249
|
+
where
|
250
|
+
b_o >= a_o >= 4
|
251
|
+
b_u >= a_u >= 4
|
252
|
+
|
253
|
+
Condition (i) may not be respected if
|
254
|
+
one can assume in this case that ah=am=al=0
|
255
|
+
|
256
|
+
Guarantees: TODO
|
257
|
+
Details: resh, resm and resl are considered to be pointers
|
258
|
+
*/
|
259
|
+
|
260
|
+
#define Add33Cond(resh, resm, resl, ah, am, al, bh, bm, bl) \
|
261
|
+
{ \
|
262
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7, _t8; \
|
263
|
+
\
|
264
|
+
Add12Cond((*(resh)),_t1,(ah),(bh)); \
|
265
|
+
Add12Cond(_t2,_t3,(am),(bm)); \
|
266
|
+
_t6 = (al) + (bl); \
|
267
|
+
Add12Cond(_t7,_t4,_t1,_t2); \
|
268
|
+
_t5 = _t3 + _t4; \
|
269
|
+
_t8 = _t5 + _t6; \
|
270
|
+
Add12Cond((*(resm)),(*(resl)),_t7,_t8); \
|
271
|
+
}
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
/* Add233
|
276
|
+
|
277
|
+
Procedure for adding a double double number to a triple
|
278
|
+
double number resulting in a triple double number
|
279
|
+
|
280
|
+
|
281
|
+
Arguments: a double double number ah, al
|
282
|
+
a triple double number bh, bm, bl
|
283
|
+
|
284
|
+
Results: a triple double number resh, resm, resl
|
285
|
+
|
286
|
+
Preconditions: abs(ah) > abs(al)
|
287
|
+
ah and al do not overlap
|
288
|
+
ah = round-to-nearest(ah + al)
|
289
|
+
abs(bh) <= 2^(-2) * abs(ah)
|
290
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
291
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
292
|
+
where
|
293
|
+
b_o >= 2
|
294
|
+
b_u >= 1
|
295
|
+
|
296
|
+
Guarantees: resm and resl are non-overlapping
|
297
|
+
resm = round-to-nearest(resm + resl)
|
298
|
+
abs(resm) <= 2^(\gamma) * abs(resh)
|
299
|
+
where
|
300
|
+
\gamma >= min(45,b_o-4,b_o+b_u-2)
|
301
|
+
resh+resm+resl=((ah+al) + (bh+bm+bl)) * (1+eps)
|
302
|
+
where
|
303
|
+
abs(eps) <=
|
304
|
+
<= 2^(-b_o-b_u-52) + 2^(-b_o-104) + 2^(-153)
|
305
|
+
|
306
|
+
Details: resh, resm and resl are considered to be pointers
|
307
|
+
*/
|
308
|
+
#define Add233(resh, resm, resl, ah, al, bh, bm, bl) \
|
309
|
+
{ \
|
310
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7; \
|
311
|
+
\
|
312
|
+
Add12((*(resh)),_t1,(ah),(bh)); \
|
313
|
+
Add12Cond(_t2,_t3,(al),(bm)); \
|
314
|
+
Add12Cond(_t4,_t5,_t1,_t2); \
|
315
|
+
_t6 = _t3 + (bl); \
|
316
|
+
_t7 = _t6 + _t5; \
|
317
|
+
Add12Cond((*(resm)),(*(resl)),_t4,_t7); \
|
318
|
+
}
|
319
|
+
|
320
|
+
/* Add123
|
321
|
+
|
322
|
+
Procedure for adding a double number to a double
|
323
|
+
double number resulting in a triple double number
|
324
|
+
|
325
|
+
|
326
|
+
Arguments: a double number a
|
327
|
+
a double double number bh, bl
|
328
|
+
|
329
|
+
Results: a triple double number resh, resm, resl
|
330
|
+
|
331
|
+
Preconditions: abs(bh) <= 2^(-2) * abs(a)
|
332
|
+
abs(bl) <= 2^(-53) * abs(bh)
|
333
|
+
|
334
|
+
Guarantees: resm and resl are non-overlapping
|
335
|
+
resm = round-to-nearest(resm + resl)
|
336
|
+
abs(resm) <= 2^(-\gamma) * abs(resh)
|
337
|
+
where
|
338
|
+
|
339
|
+
\gamma >= 52
|
340
|
+
|
341
|
+
resh+resm+resl=(a + (bh+bm+bl)) exactly
|
342
|
+
|
343
|
+
|
344
|
+
Details: resh, resm and resl are considered to be pointers
|
345
|
+
*/
|
346
|
+
#define Add123(resh, resm, resl, a, bh, bl) \
|
347
|
+
{ \
|
348
|
+
double _t1; \
|
349
|
+
\
|
350
|
+
Add12((*(resh)),_t1,(a),(bh)); \
|
351
|
+
Add12((*(resm)),(*(resl)),_t1,(bl)); \
|
352
|
+
}
|
353
|
+
|
354
|
+
/* Add213
|
355
|
+
|
356
|
+
Procedure for adding a double double number to a double
|
357
|
+
number resulting in a triple double number
|
358
|
+
|
359
|
+
|
360
|
+
Arguments: a double double number ah, al
|
361
|
+
a double number b
|
362
|
+
|
363
|
+
Results: a triple double number resh, resm, resl
|
364
|
+
|
365
|
+
Preconditions: abs(b) <= 2^(-2) * abs(ah)
|
366
|
+
abs(al) <= 2^(-53) * abs(ah)
|
367
|
+
|
368
|
+
Guarantees: resm and resl are non-overlapping
|
369
|
+
resm = round-to-nearest(resm + resl)
|
370
|
+
abs(resm) <= 2^(-\gamma) * abs(resh)
|
371
|
+
where
|
372
|
+
|
373
|
+
\gamma >= 52
|
374
|
+
|
375
|
+
resh+resm+resl=(a + (bh+bm+bl)) exactly
|
376
|
+
|
377
|
+
|
378
|
+
Details: resh, resm and resl are considered to be pointers
|
379
|
+
*/
|
380
|
+
#define Add213(resh, resm, resl, ah, al, b) \
|
381
|
+
{ \
|
382
|
+
double _t1; \
|
383
|
+
\
|
384
|
+
Add12((*(resh)),_t1,(ah),(b)); \
|
385
|
+
Add12Cond((*(resm)),(*(resl)),(al),(b)); \
|
386
|
+
}
|
387
|
+
|
388
|
+
|
389
|
+
|
390
|
+
/* Add23
|
391
|
+
|
392
|
+
Procedure for adding a double-double number to a double-double
|
393
|
+
number resulting in a triple double number
|
394
|
+
|
395
|
+
|
396
|
+
Arguments: a double double number ah, al
|
397
|
+
a double double number bh, bl
|
398
|
+
|
399
|
+
Results: a triple double number resh, resm, resl
|
400
|
+
|
401
|
+
Preconditions: abs(bh) <= 2^(-2) * abs(ah)
|
402
|
+
abs(al) <= 2^(-53) * abs(ah)
|
403
|
+
abs(bl) <= 2^(-53) * abs(bh)
|
404
|
+
|
405
|
+
Guarantees: TO DO
|
406
|
+
|
407
|
+
|
408
|
+
Details: resh, resm and resl are considered to be pointers
|
409
|
+
*/
|
410
|
+
#define Add23(resh, resm, resl, ah, al, bh, bl) \
|
411
|
+
{ \
|
412
|
+
double _t1, _t2, _t3, _t4, _t5, _t6; \
|
413
|
+
\
|
414
|
+
Add12((*(resh)),_t1,(ah),(bh)); \
|
415
|
+
Add12Cond(_t2,_t3,(al),(bl)); \
|
416
|
+
Add12Cond(_t4,_t5,_t1,_t2); \
|
417
|
+
_t6 = _t3 + _t5; \
|
418
|
+
Add12Cond((*(resm)),(*(resl)),_t4,_t6); \
|
419
|
+
}
|
420
|
+
|
421
|
+
|
422
|
+
|
423
|
+
|
424
|
+
/* Add133
|
425
|
+
|
426
|
+
Procedure for adding a double number to a triple
|
427
|
+
double number resulting in a triple double number
|
428
|
+
|
429
|
+
|
430
|
+
Arguments: a double number a
|
431
|
+
a triple double number bh, bm, bl
|
432
|
+
|
433
|
+
Results: a triple double number resh, resm, resl
|
434
|
+
|
435
|
+
Preconditions: abs(bh) <= 2^(-2) * abs(a)
|
436
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
437
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
438
|
+
where
|
439
|
+
b_o >= 2
|
440
|
+
b_u >= 1
|
441
|
+
|
442
|
+
Guarantees: resm and resl are non-overlapping
|
443
|
+
resm = round-to-nearest(resm + resl)
|
444
|
+
abs(resm) <= 2^(\gamma) * abs(resh)
|
445
|
+
where
|
446
|
+
\gamma >= min(47,2-b_o,1-b_o-b_u)
|
447
|
+
resh+resm+resl=(a + (bh+bm+bl)) * (1+eps)
|
448
|
+
where
|
449
|
+
abs(eps) <=
|
450
|
+
<= 2^(-52-b_o-b_u) + 2^(-154)
|
451
|
+
|
452
|
+
|
453
|
+
Details: resh, resm and resl are considered to be pointers
|
454
|
+
*/
|
455
|
+
#define Add133(resh, resm, resl, a, bh, bm, bl) \
|
456
|
+
{ \
|
457
|
+
double _t1, _t2, _t3, _t4; \
|
458
|
+
\
|
459
|
+
Add12((*(resh)),_t1,(a),(bh)); \
|
460
|
+
Add12Cond(_t2,_t3,_t1,(bm)); \
|
461
|
+
_t4 = _t3 + (bl); \
|
462
|
+
Add12Cond((*(resm)),(*(resl)),_t2,_t4); \
|
463
|
+
}
|
464
|
+
|
465
|
+
/* Add133Cond
|
466
|
+
|
467
|
+
Procedure for adding a double number to a triple
|
468
|
+
double number resulting in a triple double number
|
469
|
+
|
470
|
+
|
471
|
+
Arguments: a double number a
|
472
|
+
a triple double number bh, bm, bl
|
473
|
+
|
474
|
+
Results: a triple double number resh, resm, resl
|
475
|
+
|
476
|
+
Preconditions: abs(bm) <= 2^(-b_o) * abs(bh)
|
477
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
478
|
+
where
|
479
|
+
b_o >= 2
|
480
|
+
b_u >= 1
|
481
|
+
|
482
|
+
Guarantees: resm and resl are non-overlapping
|
483
|
+
resm = round-to-nearest(resm + resl)
|
484
|
+
abs(resm) <= 2^(\gamma) * abs(resh)
|
485
|
+
where
|
486
|
+
|
487
|
+
TODO
|
488
|
+
|
489
|
+
resh+resm+resl=(a + (bh+bm+bl)) * (1+eps)
|
490
|
+
where
|
491
|
+
abs(eps) <=
|
492
|
+
|
493
|
+
TODO
|
494
|
+
|
495
|
+
|
496
|
+
Details: resh, resm and resl are considered to be pointers
|
497
|
+
*/
|
498
|
+
#define Add133Cond(resh, resm, resl, a, bh, bm, bl) \
|
499
|
+
{ \
|
500
|
+
double _t1, _t2, _t3, _t4; \
|
501
|
+
\
|
502
|
+
Add12Cond((*(resh)),_t1,(a),(bh)); \
|
503
|
+
Add12Cond(_t2,_t3,_t1,(bm)); \
|
504
|
+
_t4 = _t3 + (bl); \
|
505
|
+
Add12Cond((*(resm)),(*(resl)),_t2,_t4); \
|
506
|
+
}
|
507
|
+
|
508
|
+
|
509
|
+
|
510
|
+
/* Add233Cond
|
511
|
+
|
512
|
+
Procedure for adding a double double number to a triple
|
513
|
+
double number resulting in a triple double number
|
514
|
+
|
515
|
+
|
516
|
+
Arguments: a double double number ah, al
|
517
|
+
a triple double number bh, bm, bl
|
518
|
+
|
519
|
+
Results: a triple double number resh, resm, resl
|
520
|
+
|
521
|
+
Preconditions: abs(ah) > abs(al)
|
522
|
+
ah and al do not overlap
|
523
|
+
ah = round-to-nearest(ah + al)
|
524
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
525
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
526
|
+
where
|
527
|
+
b_o >= 2
|
528
|
+
b_u >= 1
|
529
|
+
|
530
|
+
Guarantees: resm and resl are non-overlapping
|
531
|
+
resm = round-to-nearest(resm + resl)
|
532
|
+
abs(resm) <= 2^(\gamma) * abs(resh)
|
533
|
+
where
|
534
|
+
\gamma >= ????
|
535
|
+
resh+resm+resl=((ah+al) + (bh+bm+bl)) * (1+eps)
|
536
|
+
where
|
537
|
+
abs(eps) <=
|
538
|
+
<= ????
|
539
|
+
|
540
|
+
Details: resh, resm and resl are considered to be pointers
|
541
|
+
*/
|
542
|
+
#define Add233Cond(resh, resm, resl, ah, al, bh, bm, bl) \
|
543
|
+
{ \
|
544
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7; \
|
545
|
+
\
|
546
|
+
Add12Cond((*(resh)),_t1,(ah),(bh)); \
|
547
|
+
Add12Cond(_t2,_t3,(al),(bm)); \
|
548
|
+
Add12Cond(_t4,_t5,_t1,_t2); \
|
549
|
+
_t6 = _t3 + (bl); \
|
550
|
+
_t7 = _t6 + _t5; \
|
551
|
+
Add12Cond((*(resm)),(*(resl)),_t4,_t7); \
|
552
|
+
}
|
553
|
+
|
554
|
+
|
555
|
+
|
556
|
+
|
557
|
+
/* Mul33
|
558
|
+
|
559
|
+
Procedure for multiplying two triple double numbers resulting
|
560
|
+
in a triple double number
|
561
|
+
|
562
|
+
|
563
|
+
Arguments: two triple double numbers:
|
564
|
+
ah, am, al and
|
565
|
+
bh, bm, bl
|
566
|
+
|
567
|
+
Results: a triple double number resh, resm, resl
|
568
|
+
|
569
|
+
Preconditions: abs(am) <= 2^(-a_o) * abs(ah)
|
570
|
+
abs(al) <= 2^(-a_u) * abs(am)
|
571
|
+
abs(bm) <= 2^(-b_o) * abs(bh)
|
572
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
573
|
+
where
|
574
|
+
b_o, a_o >= 5
|
575
|
+
b_u, a_u >= 5
|
576
|
+
|
577
|
+
|
578
|
+
Guarantees: resm and resl are non-overlapping
|
579
|
+
resm = round-to-nearest(resm + resl)
|
580
|
+
abs(resm) <= 2^(-g_o) * abs(resh)
|
581
|
+
with
|
582
|
+
g_o > min(48,-4+a_o,-4+b_o,-4+a_o-b_o)
|
583
|
+
resh+resm+resl = (ah+am+al) * (bh+bm+bl) * (1+eps)
|
584
|
+
where
|
585
|
+
abs(eps) <= 2^-151 + 2^-99-a_o + 2^-99-b_o +
|
586
|
+
+ 2^-49-a_o-a_u + 2^-49-b_o-b_u + 2^50-a_o-b_o-b_u +
|
587
|
+
+ 2^50-a_o-b_o-b_u + 2^-101-a_o-b_o + 2^-52-a_o-a_u-b_o-b_u
|
588
|
+
|
589
|
+
Details: resh, resm and resl are considered to be pointers
|
590
|
+
*/
|
591
|
+
|
592
|
+
#define DoMul33(resh, resm, resl, ah, am, al, bh, bm, bl) \
|
593
|
+
{ \
|
594
|
+
double _t1, _t2, _t3, _t4, _t5, _t6, _t7, _t8, _t9; \
|
595
|
+
double _t10, _t11, _t12, _t13, _t14, _t15, _t16, _t17; \
|
596
|
+
double _t18, _t19, _t20, _t21, _t22; \
|
597
|
+
\
|
598
|
+
Mul12((resh),&_t1,(ah),(bh)); \
|
599
|
+
Mul12(&_t2,&_t3,(ah),(bm)); \
|
600
|
+
Mul12(&_t4,&_t5,(am),(bh)); \
|
601
|
+
Mul12(&_t6,&_t7,(am),(bm)); \
|
602
|
+
_t8 = (ah) * (bl); \
|
603
|
+
_t9 = (al) * (bh); \
|
604
|
+
_t10 = (am) * (bl); \
|
605
|
+
_t11 = (al) * (bm); \
|
606
|
+
_t12 = _t8 + _t9; \
|
607
|
+
_t13 = _t10 + _t11; \
|
608
|
+
Add12Cond(_t14,_t15,_t1,_t6); \
|
609
|
+
_t16 = _t7 + _t15; \
|
610
|
+
_t17 = _t12 + _t13; \
|
611
|
+
_t18 = _t16 + _t17; \
|
612
|
+
Add12Cond(_t19,_t20,_t14,_t18); \
|
613
|
+
Add22Cond(&_t21,&_t22,_t2,_t3,_t4,_t5); \
|
614
|
+
Add22Cond((resm),(resl),_t21,_t22,_t19,_t20); \
|
615
|
+
}
|
616
|
+
|
617
|
+
|
618
|
+
/* Mul133
|
619
|
+
|
620
|
+
Procedure for multiplying double by a triple double number resulting
|
621
|
+
in a triple double number
|
622
|
+
|
623
|
+
|
624
|
+
Arguments: a double a
|
625
|
+
a triple double bh, bm, bl
|
626
|
+
|
627
|
+
Results: a triple double number resh, resm, resl
|
628
|
+
|
629
|
+
Preconditions: abs(bm) <= 2^(-b_o) * abs(bh)
|
630
|
+
abs(bl) <= 2^(-b_u) * abs(bm)
|
631
|
+
where
|
632
|
+
b_o >= 2
|
633
|
+
b_u >= 2
|
634
|
+
|
635
|
+
|
636
|
+
Guarantees: resm and resl are non-overlapping
|
637
|
+
resm = round-to-nearest(resm + resl)
|
638
|
+
abs(resm) <= 2^(-g_o) * abs(resh)
|
639
|
+
with
|
640
|
+
g_o > min(47,-5-b_o,-5+b_o+b_u)
|
641
|
+
resh+resm+resl = a * (bh+bm+bl) * (1+eps)
|
642
|
+
where
|
643
|
+
abs(eps) <= 2^-49-b_o-b_u + 2^-101-b_o + 2^-156
|
644
|
+
|
645
|
+
Details: resh, resm and resl are considered to be pointers
|
646
|
+
*/
|
647
|
+
#define DoMul133(resh, resm, resl, a, bh, bm, bl) \
|
648
|
+
{ \
|
649
|
+
double _t2, _t3, _t4, _t5, _t7, _t8, _t9, _t10; \
|
650
|
+
\
|
651
|
+
Mul12((resh),&_t2,(a),(bh)); \
|
652
|
+
Mul12(&_t3,&_t4,(a),(bm)); \
|
653
|
+
_t5 = (a) * (bl); \
|
654
|
+
Add12Cond(_t9,_t7,_t2,_t3); \
|
655
|
+
_t8 = _t4 + _t5; \
|
656
|
+
_t10 = _t7 + _t8; \
|
657
|
+
Add12Cond((*(resm)),(*(resl)),_t9,_t10); \
|
658
|
+
}
|
659
|
+
|
660
|
+
/* Mul123
|
661
|
+
|
662
|
+
Procedure for multiplying double by a double double number resulting
|
663
|
+
in a triple double number
|
664
|
+
|
665
|
+
|
666
|
+
Arguments: a double a
|
667
|
+
a double double bh, bl
|
668
|
+
|
669
|
+
Results: a triple double number resh, resm, resl
|
670
|
+
|
671
|
+
Guarantees: resm and resl are non-overlapping
|
672
|
+
resm = round-to-nearest(resm + resl)
|
673
|
+
abs(resm) <= 2^(-g_o) * abs(resh)
|
674
|
+
with
|
675
|
+
g_o > 47
|
676
|
+
resh+resm+resl = a * (bh+bm) * (1+eps)
|
677
|
+
where
|
678
|
+
abs(eps) <= 2^-154
|
679
|
+
|
680
|
+
Details: resh, resm and resl are considered to be pointers
|
681
|
+
*/
|
682
|
+
#define DoMul123(resh, resm, resl, a, bh, bl) \
|
683
|
+
{ \
|
684
|
+
double _t1, _t2, _t3, _t4, _t5, _t6; \
|
685
|
+
\
|
686
|
+
Mul12((resh),&_t1,(a),(bh)); \
|
687
|
+
Mul12(&_t2,&_t3,(a),(bl)); \
|
688
|
+
Add12Cond(_t5,_t4,_t1,_t2); \
|
689
|
+
_t6 = _t3 + _t4; \
|
690
|
+
Add12Cond((*(resm)),(*(resl)),_t5,_t6); \
|
691
|
+
}
|
692
|
+
|
693
|
+
|
694
|
+
|
695
|
+
/* ReturnRoundToNearest3
|
696
|
+
|
697
|
+
Procedure for rounding a triple to a double number
|
698
|
+
in round-to-nearest-ties-to-even mode.
|
699
|
+
|
700
|
+
|
701
|
+
Arguments: a triple double number xh, xm, xl
|
702
|
+
|
703
|
+
Results: a double number xprime
|
704
|
+
returned by a return-statement
|
705
|
+
|
706
|
+
Preconditions: xh, xm and xl are non-overlapping
|
707
|
+
xm = RN(xm +math xl)
|
708
|
+
xh != 0, xm != 0
|
709
|
+
xl = 0 iff xm != +/- 0.5 * ulp(xh) (0.25 if xh = 2^e)
|
710
|
+
|
711
|
+
Guarantees: xprime = RN(xh + xm + xl)
|
712
|
+
|
713
|
+
Sideeffects: returns, i.e. leaves the function
|
714
|
+
|
715
|
+
*/
|
716
|
+
#define ReturnRoundToNearest3(xh,xm,xl) \
|
717
|
+
{ \
|
718
|
+
double _t1, _t2, _t3, _t4, _t5, _t6; \
|
719
|
+
db_number _xp, _xn; \
|
720
|
+
\
|
721
|
+
_xp.d = (xh); \
|
722
|
+
_xn.i[HI] = _xp.i[HI]; \
|
723
|
+
_xn.i[LO] = _xp.i[LO]; \
|
724
|
+
_xn.l--; \
|
725
|
+
_t1 = _xn.d; \
|
726
|
+
_xp.l++; \
|
727
|
+
_t4 = _xp.d; \
|
728
|
+
_t2 = (xh) - _t1; \
|
729
|
+
_t3 = _t2 * -0.5; \
|
730
|
+
_t5 = _t4 - (xh); \
|
731
|
+
_t6 = _t5 * 0.5; \
|
732
|
+
if (((xm) != _t3) && ((xm) != _t6)) return ((xh) + (xm)); \
|
733
|
+
if ((xm) * (xl) > 0.0) { \
|
734
|
+
if ((xh) * (xl) > 0.0) \
|
735
|
+
return _t4; \
|
736
|
+
else \
|
737
|
+
return _t1; \
|
738
|
+
} else return (xh); \
|
739
|
+
}
|
740
|
+
|
741
|
+
/* ReturnRoundToNearest3Other
|
742
|
+
|
743
|
+
ATTENTION: THIS CURRENTLY UNPROVEN CODE !!!
|
744
|
+
|
745
|
+
Procedure for rounding a triple to a double number
|
746
|
+
in round-to-nearest-ties-to-even mode.
|
747
|
+
|
748
|
+
|
749
|
+
Arguments: a triple double number xh, xm, xl
|
750
|
+
|
751
|
+
Results: a double number xprime
|
752
|
+
returned by a return-statement
|
753
|
+
|
754
|
+
Preconditions: |xm + xl| <= 2^(-5) * |xh|
|
755
|
+
|
756
|
+
Guarantees: xprime = RN(xh + xm + xl)
|
757
|
+
|
758
|
+
Sideeffects: returns, i.e. leaves the function
|
759
|
+
|
760
|
+
*/
|
761
|
+
#define ReturnRoundToNearest3Other(xh,xm,xl) \
|
762
|
+
{ \
|
763
|
+
double _t3, _t4; \
|
764
|
+
db_number _t3db; \
|
765
|
+
\
|
766
|
+
Add12(_t3,_t4,(xm),(xl)); \
|
767
|
+
if (_t4 != 0.0) { \
|
768
|
+
_t3db.d = _t3; \
|
769
|
+
if (!(_t3db.i[LO] & 0x00000001)) { \
|
770
|
+
if ((_t4 > 0.0) ^ ((_t3db.i[HI] & 0x80000000) != 0)) \
|
771
|
+
_t3db.l++; \
|
772
|
+
else \
|
773
|
+
_t3db.l--; \
|
774
|
+
_t3 = _t3db.d; \
|
775
|
+
} \
|
776
|
+
} \
|
777
|
+
return (xh) + _t3; \
|
778
|
+
}
|
779
|
+
|
780
|
+
|
781
|
+
|
782
|
+
/* ReturnRoundUpwards3
|
783
|
+
|
784
|
+
Procedure for rounding a triple to a double number
|
785
|
+
in round-upwards mode.
|
786
|
+
|
787
|
+
|
788
|
+
Arguments: a triple double number xh, xm, xl
|
789
|
+
|
790
|
+
Results: a double number xprime
|
791
|
+
returned by a return-statement
|
792
|
+
|
793
|
+
Preconditions: xh, xm and xl are non-overlapping
|
794
|
+
xm = RN(xm +math xl)
|
795
|
+
xh != 0, xm != 0
|
796
|
+
|
797
|
+
Exact algebraic images have already
|
798
|
+
been filtered out.
|
799
|
+
|
800
|
+
Guarantees: xprime = RU(xh + xm + xl)
|
801
|
+
|
802
|
+
Sideeffects: returns, i.e. leaves the function
|
803
|
+
|
804
|
+
*/
|
805
|
+
#define ReturnRoundUpwards3(xh,xm,xl) \
|
806
|
+
{ \
|
807
|
+
double _t1, _t2, _t3; \
|
808
|
+
db_number _tdb; \
|
809
|
+
\
|
810
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
811
|
+
_t3 = _t2 + (xl); \
|
812
|
+
if (_t3 > 0.0) { \
|
813
|
+
if (_t1 > 0.0) { \
|
814
|
+
_tdb.d = _t1; \
|
815
|
+
_tdb.l++; \
|
816
|
+
return _tdb.d; \
|
817
|
+
} else { \
|
818
|
+
_tdb.d = _t1; \
|
819
|
+
_tdb.l--; \
|
820
|
+
return _tdb.d; \
|
821
|
+
} \
|
822
|
+
} else return _t1; \
|
823
|
+
}
|
824
|
+
|
825
|
+
|
826
|
+
/* ReturnRoundDownwards3
|
827
|
+
|
828
|
+
Procedure for rounding a triple to a double number
|
829
|
+
in round-downwards mode.
|
830
|
+
|
831
|
+
|
832
|
+
Arguments: a triple double number xh, xm, xl
|
833
|
+
|
834
|
+
Results: a double number xprime
|
835
|
+
returned by a return-statement
|
836
|
+
|
837
|
+
Preconditions: xh, xm and xl are non-overlapping
|
838
|
+
xm = RN(xm +math xl)
|
839
|
+
xh != 0, xm != 0
|
840
|
+
|
841
|
+
Exact algebraic images have already
|
842
|
+
been filtered out.
|
843
|
+
|
844
|
+
Guarantees: xprime = RD(xh + xm + xl)
|
845
|
+
|
846
|
+
Sideeffects: returns, i.e. leaves the function
|
847
|
+
|
848
|
+
*/
|
849
|
+
#define ReturnRoundDownwards3(xh,xm,xl) \
|
850
|
+
{ \
|
851
|
+
double _t1, _t2, _t3; \
|
852
|
+
db_number _tdb; \
|
853
|
+
\
|
854
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
855
|
+
_t3 = _t2 + (xl); \
|
856
|
+
if (_t3 < 0.0) { \
|
857
|
+
if (_t1 > 0.0) { \
|
858
|
+
_tdb.d = _t1; \
|
859
|
+
_tdb.l--; \
|
860
|
+
return _tdb.d; \
|
861
|
+
} else { \
|
862
|
+
_tdb.d = _t1; \
|
863
|
+
_tdb.l++; \
|
864
|
+
return _tdb.d; \
|
865
|
+
} \
|
866
|
+
} else return _t1; \
|
867
|
+
}
|
868
|
+
|
869
|
+
|
870
|
+
/* ReturnRoundTowardsZero3
|
871
|
+
|
872
|
+
Procedure for rounding a triple to a double number
|
873
|
+
in round-towards-zero mode.
|
874
|
+
|
875
|
+
|
876
|
+
Arguments: a triple double number xh, xm, xl
|
877
|
+
|
878
|
+
Results: a double number xprime
|
879
|
+
returned by a return-statement
|
880
|
+
|
881
|
+
Preconditions: xh, xm and xl are non-overlapping
|
882
|
+
xm = RN(xm +math xl)
|
883
|
+
xh != 0, xm != 0
|
884
|
+
|
885
|
+
Exact algebraic images have already
|
886
|
+
been filtered out.
|
887
|
+
|
888
|
+
Guarantees: xprime = RZ(xh + xm + xl)
|
889
|
+
|
890
|
+
Sideeffects: returns, i.e. leaves the function
|
891
|
+
|
892
|
+
*/
|
893
|
+
#define ReturnRoundTowardsZero3(xh,xm,xl) \
|
894
|
+
{ \
|
895
|
+
double _t1, _t2, _t3; \
|
896
|
+
db_number _tdb; \
|
897
|
+
\
|
898
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
899
|
+
_t3 = _t2 + (xl); \
|
900
|
+
if (_t1 > 0.0) { \
|
901
|
+
if (_t3 < 0.0) { \
|
902
|
+
_tdb.d = _t1; \
|
903
|
+
_tdb.l--; \
|
904
|
+
return _tdb.d; \
|
905
|
+
} else return _t1; \
|
906
|
+
} else { \
|
907
|
+
if (_t3 > 0.0) { \
|
908
|
+
_tdb.d = _t1; \
|
909
|
+
_tdb.l--; \
|
910
|
+
return _tdb.d; \
|
911
|
+
} else return _t1; \
|
912
|
+
} \
|
913
|
+
}
|
914
|
+
|
915
|
+
|
916
|
+
/* ReturnRoundUpwards3Unfiltered
|
917
|
+
|
918
|
+
Procedure for rounding a triple to a double number
|
919
|
+
in round-upwards mode.
|
920
|
+
|
921
|
+
|
922
|
+
Arguments: a triple double number xh, xm, xl
|
923
|
+
a double constant wca representing 2^k
|
924
|
+
where 2^-k is Lefevre's worst case accuracy
|
925
|
+
|
926
|
+
Results: a double number xprime
|
927
|
+
returned by a return-statement
|
928
|
+
|
929
|
+
Preconditions: xh, xm and xl are non-overlapping
|
930
|
+
xm = RN(xm +math xl)
|
931
|
+
xh != 0, xm != 0
|
932
|
+
|
933
|
+
Guarantees: xprime = RU(xh + xm + xl)
|
934
|
+
|
935
|
+
Sideeffects: returns, i.e. leaves the function
|
936
|
+
|
937
|
+
*/
|
938
|
+
#define ReturnRoundUpwards3Unfiltered(xh,xm,xl,wca) \
|
939
|
+
{ \
|
940
|
+
double _t1, _t2, _t3; \
|
941
|
+
db_number _tdb, _tdb2; \
|
942
|
+
\
|
943
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
944
|
+
_t3 = _t2 + (xl); \
|
945
|
+
if (_t3 > 0.0) { \
|
946
|
+
_tdb2.d = wca * _t3; \
|
947
|
+
_tdb.d = _t1; \
|
948
|
+
if ((_tdb2.i[HI] & 0x7ff00000) < (_tdb.i[HI] & 0x7ff00000)) \
|
949
|
+
return _t1; \
|
950
|
+
if (_t1 > 0.0) { \
|
951
|
+
_tdb.l++; \
|
952
|
+
return _tdb.d; \
|
953
|
+
} else { \
|
954
|
+
_tdb.l--; \
|
955
|
+
return _tdb.d; \
|
956
|
+
} \
|
957
|
+
} else return _t1; \
|
958
|
+
}
|
959
|
+
|
960
|
+
|
961
|
+
|
962
|
+
/* ReturnRoundDownwards3Unfiltered
|
963
|
+
|
964
|
+
Procedure for rounding a triple to a double number
|
965
|
+
in round-downwards mode.
|
966
|
+
|
967
|
+
|
968
|
+
Arguments: a triple double number xh, xm, xl
|
969
|
+
a double constant wca representing 2^k
|
970
|
+
where 2^-k is Lefevre's worst case accuracy
|
971
|
+
|
972
|
+
Results: a double number xprime
|
973
|
+
returned by a return-statement
|
974
|
+
|
975
|
+
Preconditions: xh, xm and xl are non-overlapping
|
976
|
+
xm = RN(xm +math xl)
|
977
|
+
xh != 0, xm != 0
|
978
|
+
|
979
|
+
Guarantees: xprime = RD(xh + xm + xl)
|
980
|
+
|
981
|
+
Sideeffects: returns, i.e. leaves the function
|
982
|
+
|
983
|
+
*/
|
984
|
+
#define ReturnRoundDownwards3Unfiltered(xh,xm,xl,wca) \
|
985
|
+
{ \
|
986
|
+
double _t1, _t2, _t3; \
|
987
|
+
db_number _tdb, _tdb2; \
|
988
|
+
\
|
989
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
990
|
+
_t3 = _t2 + (xl); \
|
991
|
+
if (_t3 < 0.0) { \
|
992
|
+
_tdb2.d = wca * _t3; \
|
993
|
+
_tdb.d = _t1; \
|
994
|
+
if ((_tdb2.i[HI] & 0x7ff00000) < (_tdb.i[HI] & 0x7ff00000)) \
|
995
|
+
return _t1; \
|
996
|
+
if (_t1 > 0.0) { \
|
997
|
+
_tdb.l--; \
|
998
|
+
return _tdb.d; \
|
999
|
+
} else { \
|
1000
|
+
_tdb.l++; \
|
1001
|
+
return _tdb.d; \
|
1002
|
+
} \
|
1003
|
+
} else return _t1; \
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
/* ReturnRoundTowardsZero3Unfiltered
|
1007
|
+
|
1008
|
+
Procedure for rounding a triple to a double number
|
1009
|
+
in round-towards-zero mode.
|
1010
|
+
|
1011
|
+
|
1012
|
+
Arguments: a triple double number xh, xm, xl
|
1013
|
+
a double constant wca representing 2^k
|
1014
|
+
where 2^-k is Lefevre's worst case accuracy
|
1015
|
+
|
1016
|
+
Results: a double number xprime
|
1017
|
+
returned by a return-statement
|
1018
|
+
|
1019
|
+
Preconditions: xh, xm and xl are non-overlapping
|
1020
|
+
xm = RN(xm +math xl)
|
1021
|
+
xh != 0, xm != 0
|
1022
|
+
|
1023
|
+
Guarantees: xprime = RZ(xh + xm + xl)
|
1024
|
+
|
1025
|
+
Sideeffects: returns, i.e. leaves the function
|
1026
|
+
|
1027
|
+
*/
|
1028
|
+
#define ReturnRoundTowardsZero3Unfiltered(xh,xm,xl,wca) \
|
1029
|
+
{ \
|
1030
|
+
if ((xh) > 0) \
|
1031
|
+
ReturnRoundDownwards3Unfiltered((xh),(xm),(xl),(wca)) \
|
1032
|
+
else \
|
1033
|
+
ReturnRoundUpwards3Unfiltered((xh),(xm),(xl),(wca)) \
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
/* RoundToNearest3
|
1037
|
+
|
1038
|
+
Procedure for rounding a triple to a double number
|
1039
|
+
in round-to-nearest-ties-to-even mode.
|
1040
|
+
|
1041
|
+
|
1042
|
+
Arguments: a triple double number xh, xm, xl
|
1043
|
+
|
1044
|
+
Results: a double number xprime
|
1045
|
+
returned by a return-statement
|
1046
|
+
|
1047
|
+
Preconditions: xh, xm and xl are non-overlapping
|
1048
|
+
xm = RN(xm +math xl)
|
1049
|
+
xh != 0, xm != 0
|
1050
|
+
xl = 0 iff xm != +/- 0.5 * ulp(xh) (0.25 if xh = 2^e)
|
1051
|
+
|
1052
|
+
Guarantees: xprime = RN(xh + xm + xl)
|
1053
|
+
|
1054
|
+
Details: res is considered to be a pointer
|
1055
|
+
|
1056
|
+
*/
|
1057
|
+
#define RoundToNearest3(res,xh,xm,xl) \
|
1058
|
+
{ \
|
1059
|
+
double _t1, _t2, _t3, _t4, _t5, _t6; \
|
1060
|
+
db_number _xp, _xn; \
|
1061
|
+
\
|
1062
|
+
_xp.d = (xh); \
|
1063
|
+
_xn.i[HI] = _xp.i[HI]; \
|
1064
|
+
_xn.i[LO] = _xp.i[LO]; \
|
1065
|
+
_xn.l--; \
|
1066
|
+
_t1 = _xn.d; \
|
1067
|
+
_xp.l++; \
|
1068
|
+
_t4 = _xp.d; \
|
1069
|
+
_t2 = (xh) - _t1; \
|
1070
|
+
_t3 = _t2 * -0.5; \
|
1071
|
+
_t5 = _t4 - (xh); \
|
1072
|
+
_t6 = _t5 * 0.5; \
|
1073
|
+
if (((xm) != _t3) && ((xm) != _t6)) \
|
1074
|
+
(*(res)) = ((xh) + (xm)); \
|
1075
|
+
else { \
|
1076
|
+
if ((xm) * (xl) > 0.0) { \
|
1077
|
+
if ((xh) * (xl) > 0.0) \
|
1078
|
+
(*(res)) = _t4; \
|
1079
|
+
else \
|
1080
|
+
(*(res)) = _t1; \
|
1081
|
+
} else (*(res)) = (xh); \
|
1082
|
+
} \
|
1083
|
+
}
|
1084
|
+
|
1085
|
+
/* RoundUpwards3
|
1086
|
+
|
1087
|
+
Procedure for rounding a triple to a double number
|
1088
|
+
in round-upwards mode.
|
1089
|
+
|
1090
|
+
|
1091
|
+
Arguments: a triple double number xh, xm, xl
|
1092
|
+
|
1093
|
+
Results: a double number xprime
|
1094
|
+
returned by a return-statement
|
1095
|
+
|
1096
|
+
Preconditions: xh, xm and xl are non-overlapping
|
1097
|
+
xm = RN(xm +math xl)
|
1098
|
+
xh != 0, xm != 0
|
1099
|
+
|
1100
|
+
Exact algebraic images have already
|
1101
|
+
been filtered out.
|
1102
|
+
|
1103
|
+
Guarantees: xprime = RU(xh + xm + xl)
|
1104
|
+
|
1105
|
+
Details: res is considered to be a pointer
|
1106
|
+
|
1107
|
+
*/
|
1108
|
+
#define RoundUpwards3(res,xh,xm,xl) \
|
1109
|
+
{ \
|
1110
|
+
double _t1, _t2, _t3; \
|
1111
|
+
db_number _tdb; \
|
1112
|
+
\
|
1113
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
1114
|
+
_t3 = _t2 + (xl); \
|
1115
|
+
if (_t3 > 0.0) { \
|
1116
|
+
if (_t1 > 0.0) { \
|
1117
|
+
_tdb.d = _t1; \
|
1118
|
+
_tdb.l++; \
|
1119
|
+
(*(res)) = _tdb.d; \
|
1120
|
+
} else { \
|
1121
|
+
_tdb.d = _t1; \
|
1122
|
+
_tdb.l--; \
|
1123
|
+
(*(res)) = _tdb.d; \
|
1124
|
+
} \
|
1125
|
+
} else (*(res)) = _t1; \
|
1126
|
+
}
|
1127
|
+
|
1128
|
+
|
1129
|
+
/* RoundDownwards3
|
1130
|
+
|
1131
|
+
Procedure for rounding a triple to a double number
|
1132
|
+
in round-downwards mode.
|
1133
|
+
|
1134
|
+
|
1135
|
+
Arguments: a triple double number xh, xm, xl
|
1136
|
+
|
1137
|
+
Results: a double number xprime
|
1138
|
+
returned by a return-statement
|
1139
|
+
|
1140
|
+
Preconditions: xh, xm and xl are non-overlapping
|
1141
|
+
xm = RN(xm +math xl)
|
1142
|
+
xh != 0, xm != 0
|
1143
|
+
|
1144
|
+
Exact algebraic images have already
|
1145
|
+
been filtered out.
|
1146
|
+
|
1147
|
+
Guarantees: xprime = RD(xh + xm + xl)
|
1148
|
+
|
1149
|
+
Details: res is considered to be a pointer
|
1150
|
+
|
1151
|
+
*/
|
1152
|
+
#define RoundDownwards3(res,xh,xm,xl) \
|
1153
|
+
{ \
|
1154
|
+
double _t1, _t2, _t3; \
|
1155
|
+
db_number _tdb; \
|
1156
|
+
\
|
1157
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
1158
|
+
_t3 = _t2 + (xl); \
|
1159
|
+
if (_t3 < 0.0) { \
|
1160
|
+
if (_t1 > 0.0) { \
|
1161
|
+
_tdb.d = _t1; \
|
1162
|
+
_tdb.l--; \
|
1163
|
+
(*(res)) = _tdb.d; \
|
1164
|
+
} else { \
|
1165
|
+
_tdb.d = _t1; \
|
1166
|
+
_tdb.l++; \
|
1167
|
+
(*(res)) = _tdb.d; \
|
1168
|
+
} \
|
1169
|
+
} else (*(res)) = _t1; \
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
|
1173
|
+
/* RoundTowardsZero3
|
1174
|
+
|
1175
|
+
Procedure for rounding a triple to a double number
|
1176
|
+
in round-towards-zero mode.
|
1177
|
+
|
1178
|
+
|
1179
|
+
Arguments: a triple double number xh, xm, xl
|
1180
|
+
|
1181
|
+
Results: a double number xprime
|
1182
|
+
returned by a return-statement
|
1183
|
+
|
1184
|
+
Preconditions: xh, xm and xl are non-overlapping
|
1185
|
+
xm = RN(xm +math xl)
|
1186
|
+
xh != 0, xm != 0
|
1187
|
+
|
1188
|
+
Exact algebraic images have already
|
1189
|
+
been filtered out.
|
1190
|
+
|
1191
|
+
Guarantees: xprime = RZ(xh + xm + xl)
|
1192
|
+
|
1193
|
+
Details: res is considered to be a pointer
|
1194
|
+
|
1195
|
+
*/
|
1196
|
+
#define RoundTowardsZero3(res,xh,xm,xl) \
|
1197
|
+
{ \
|
1198
|
+
double _t1, _t2, _t3; \
|
1199
|
+
db_number _tdb; \
|
1200
|
+
\
|
1201
|
+
Add12(_t1,_t2,(xh),(xm)); \
|
1202
|
+
_t3 = _t2 + (xl); \
|
1203
|
+
if (_t1 > 0.0) { \
|
1204
|
+
if (_t3 < 0.0) { \
|
1205
|
+
_tdb.d = _t1; \
|
1206
|
+
_tdb.l--; \
|
1207
|
+
(*(res)) = _tdb.d; \
|
1208
|
+
} else (*(res)) = _t1; \
|
1209
|
+
} else { \
|
1210
|
+
if (_t3 > 0.0) { \
|
1211
|
+
_tdb.d = _t1; \
|
1212
|
+
_tdb.l--; \
|
1213
|
+
(*(res)) = _tdb.d; \
|
1214
|
+
} else (*(res)) = _t1; \
|
1215
|
+
} \
|
1216
|
+
}
|
1217
|
+
|
1218
|
+
/* sqrt13
|
1219
|
+
|
1220
|
+
Computes a triple-double approximation of sqrt(x)
|
1221
|
+
|
1222
|
+
Should be provable to be exact to at least 140 bits.
|
1223
|
+
|
1224
|
+
Only handles the following special cases:
|
1225
|
+
- x == 0
|
1226
|
+
- subnormal x
|
1227
|
+
The following cases are not handled:
|
1228
|
+
- x < 0
|
1229
|
+
- x = +/-Infty, NaN
|
1230
|
+
|
1231
|
+
*/
|
1232
|
+
|
1233
|
+
|
1234
|
+
#define DoSqrt13(resh, resm, resl , x) \
|
1235
|
+
{ \
|
1236
|
+
db_number _xdb; \
|
1237
|
+
int _E; \
|
1238
|
+
double _m, _r0, _r1, _r2, _r3h, _r3l, _r4h, _r4l; \
|
1239
|
+
double _r5h, _r5m, _r5l, _srtmh, _srtml, _srtmm; \
|
1240
|
+
double _r2PHr2h, _r2PHr2l, _r2Sqh, _r2Sql; \
|
1241
|
+
double _mMr2h, _mMr2l, _mMr2Ch, _mMr2Cl; \
|
1242
|
+
double _MHmMr2Ch, _MHmMr2Cl; \
|
1243
|
+
double _r3Sqh, _r3Sql, _mMr3Sqh, _mMr3Sql; \
|
1244
|
+
double _srtmhover,_srtmmover,_srtmlover; \
|
1245
|
+
double _HmMr4Sqm,_HmMr4Sql, _mMr4Sqhover, _mMr4Sqmover, _mMr4Sqlover; \
|
1246
|
+
double _mMr4Sqh, _mMr4Sqm, _mMr4Sql, _r4Sqh, _r4Sqm, _r4Sql; \
|
1247
|
+
\
|
1248
|
+
/* Special case x = 0 */ \
|
1249
|
+
if ((x) == 0) { \
|
1250
|
+
(*(resh)) = (x); \
|
1251
|
+
(*(resm)) = 0; \
|
1252
|
+
(*(resl)) = 0; \
|
1253
|
+
} else { \
|
1254
|
+
\
|
1255
|
+
_E = 0; \
|
1256
|
+
\
|
1257
|
+
/* Convert to integer format */ \
|
1258
|
+
_xdb.d = (x); \
|
1259
|
+
\
|
1260
|
+
/* Handle subnormal case */ \
|
1261
|
+
if (_xdb.i[HI] < 0x00100000) { \
|
1262
|
+
_E = -52; \
|
1263
|
+
_xdb.d *= ((db_number) ((double) SQRTTWO52)).d; \
|
1264
|
+
/* make x a normal number */ \
|
1265
|
+
} \
|
1266
|
+
\
|
1267
|
+
/* Extract exponent E and mantissa m */ \
|
1268
|
+
_E += (_xdb.i[HI]>>20)-1023; \
|
1269
|
+
_xdb.i[HI] = (_xdb.i[HI] & 0x000fffff) | 0x3ff00000; \
|
1270
|
+
_m = _xdb.d; \
|
1271
|
+
\
|
1272
|
+
/* Make exponent even */ \
|
1273
|
+
if (_E & 0x00000001) { \
|
1274
|
+
_E++; \
|
1275
|
+
_m *= 0.5; /* Suppose now 1/2 <= m <= 2 */ \
|
1276
|
+
} \
|
1277
|
+
\
|
1278
|
+
/* Construct sqrt(2^E) = 2^(E/2) */ \
|
1279
|
+
_xdb.i[HI] = (_E/2 + 1023) << 20; \
|
1280
|
+
_xdb.i[LO] = 0; \
|
1281
|
+
\
|
1282
|
+
/* Compute initial approximation to r = 1/sqrt(m) */ \
|
1283
|
+
\
|
1284
|
+
_r0 = SQRTPOLYC0 + \
|
1285
|
+
_m * (SQRTPOLYC1 + _m * (SQRTPOLYC2 + _m * (SQRTPOLYC3 + _m * SQRTPOLYC4))); \
|
1286
|
+
\
|
1287
|
+
/* Iterate two times on double precision */ \
|
1288
|
+
\
|
1289
|
+
_r1 = 0.5 * _r0 * (3 - _m * (_r0 * _r0)); \
|
1290
|
+
_r2 = 0.5 * _r1 * (3 - _m * (_r1 * _r1)); \
|
1291
|
+
\
|
1292
|
+
/* Iterate two times on double-double precision */ \
|
1293
|
+
\
|
1294
|
+
Mul12(&_r2Sqh, &_r2Sql, _r2, _r2); \
|
1295
|
+
Add12(_r2PHr2h, _r2PHr2l, _r2, (0.5 * _r2)); \
|
1296
|
+
Mul12(&_mMr2h, &_mMr2l, _m, _r2); \
|
1297
|
+
Mul22(&_mMr2Ch, &_mMr2Cl, _mMr2h, _mMr2l, _r2Sqh, _r2Sql); \
|
1298
|
+
\
|
1299
|
+
_MHmMr2Ch = -0.5 * _mMr2Ch; \
|
1300
|
+
_MHmMr2Cl = -0.5 * _mMr2Cl; \
|
1301
|
+
\
|
1302
|
+
Add22(&_r3h, &_r3l, _r2PHr2h, _r2PHr2l, _MHmMr2Ch, _MHmMr2Cl); \
|
1303
|
+
\
|
1304
|
+
Mul22(&_r3Sqh, &_r3Sql, _r3h, _r3l, _r3h, _r3l); \
|
1305
|
+
Mul22(&_mMr3Sqh, &_mMr3Sql, _m, 0.0, _r3Sqh, _r3Sql); \
|
1306
|
+
/* To prove: mMr3Sqh = 1.0 in each case */ \
|
1307
|
+
\
|
1308
|
+
Mul22(&_r4h, &_r4l, _r3h, _r3l, 1.0, (-0.5 * _mMr3Sql)); \
|
1309
|
+
\
|
1310
|
+
/* Iterate once on triple-double precision */ \
|
1311
|
+
\
|
1312
|
+
Mul23(&_r4Sqh, &_r4Sqm, &_r4Sql, _r4h, _r4l, _r4h, _r4l); \
|
1313
|
+
Mul133(&_mMr4Sqhover, &_mMr4Sqmover, &_mMr4Sqlover, _m, _r4Sqh, _r4Sqm, _r4Sql); \
|
1314
|
+
Renormalize3(&_mMr4Sqh, &_mMr4Sqm, &_mMr4Sql, _mMr4Sqhover, _mMr4Sqmover, _mMr4Sqlover); \
|
1315
|
+
/* To prove: mMr4Sqh = 1.0 in each case */ \
|
1316
|
+
\
|
1317
|
+
_HmMr4Sqm = -0.5 * _mMr4Sqm; \
|
1318
|
+
_HmMr4Sql = -0.5 * _mMr4Sql; \
|
1319
|
+
\
|
1320
|
+
Mul233(&_r5h,&_r5m,&_r5l,_r4h,_r4l,1.0,_HmMr4Sqm,_HmMr4Sql); \
|
1321
|
+
\
|
1322
|
+
/* Multiply obtained reciprocal square root by m */ \
|
1323
|
+
\
|
1324
|
+
Mul133(&_srtmhover, &_srtmmover, &_srtmlover,_m,_r5h,_r5m,_r5l); \
|
1325
|
+
\
|
1326
|
+
Renormalize3(&_srtmh,&_srtmm,&_srtml,_srtmhover,_srtmmover,_srtmlover); \
|
1327
|
+
\
|
1328
|
+
/* Multiply componentwise by sqrt(2^E) */ \
|
1329
|
+
/* which is an integer power of 2 that may not produce a subnormal */ \
|
1330
|
+
\
|
1331
|
+
(*(resh)) = _xdb.d * _srtmh; \
|
1332
|
+
(*(resm)) = _xdb.d * _srtmm; \
|
1333
|
+
(*(resl)) = _xdb.d * _srtml; \
|
1334
|
+
\
|
1335
|
+
} /* End: special case 0 */ \
|
1336
|
+
}
|
1337
|
+
|
1338
|
+
|
1339
|
+
/* recpr33()
|
1340
|
+
|
1341
|
+
Computes a triple-double reciprocal of a triple-double
|
1342
|
+
|
1343
|
+
Should be provable to be exact to at least 140 bits
|
1344
|
+
|
1345
|
+
No special case handling is done
|
1346
|
+
|
1347
|
+
dh + dm + dl must be renormalized
|
1348
|
+
|
1349
|
+
The result is renormalized
|
1350
|
+
|
1351
|
+
*/
|
1352
|
+
|
1353
|
+
|
1354
|
+
#define DoRecpr33(resh, resm, resl, dh, dm, dl) \
|
1355
|
+
{ \
|
1356
|
+
double _rec_r1, _rec_t1, _rec_t2, _rec_t3, _rec_t4, _rec_t5, _rec_t6, _rec_t7, _rec_t8, _rec_t9, _rec_t10, _rec_t11, _rec_t12, _rec_t13, _rec_t14; \
|
1357
|
+
double _rec_r2h, _rec_r2l, _rec_t15, _rec_t16, _rec_t17, _rec_t18, _rec_t19, _rec_t20, _rec_t21, _rec_t22, _rec_t23; \
|
1358
|
+
\
|
1359
|
+
_rec_r1 = 1.0 / (dh); \
|
1360
|
+
Mul12(&_rec_t1,&_rec_t2,_rec_r1,(dh)); \
|
1361
|
+
_rec_t3 = _rec_t1 - 1.0; \
|
1362
|
+
Add12Cond(_rec_t4,_rec_t5,_rec_t3,_rec_t2); \
|
1363
|
+
Mul12(&_rec_t6,&_rec_t7,_rec_r1,(dm)); \
|
1364
|
+
Add12(_rec_t8,_rec_t9,-1.0,_rec_t6); \
|
1365
|
+
_rec_t10 = _rec_t9 + _rec_t7; \
|
1366
|
+
Add12(_rec_t11,_rec_t12,_rec_t8,_rec_t10); \
|
1367
|
+
_rec_r1 = -_rec_r1; \
|
1368
|
+
Add22Cond(&_rec_t13,&_rec_t14,_rec_t4,_rec_t5,_rec_t11,_rec_t12); \
|
1369
|
+
Mul122(&_rec_r2h,&_rec_r2l,_rec_r1,_rec_t13,_rec_t14); \
|
1370
|
+
Mul233(&_rec_t15,&_rec_t16,&_rec_t17,_rec_r2h,_rec_r2l,(dh),(dm),(dl)); \
|
1371
|
+
Renormalize3(&_rec_t18,&_rec_t19,&_rec_t20,_rec_t15,_rec_t16,_rec_t17); \
|
1372
|
+
_rec_t18 = -1.0; \
|
1373
|
+
Mul233(&_rec_t21,&_rec_t22,&_rec_t23,_rec_r2h,_rec_r2l,_rec_t18,_rec_t19,_rec_t20); \
|
1374
|
+
_rec_t21 = -_rec_t21; _rec_t22 = -_rec_t22; _rec_t23 = -_rec_t23; \
|
1375
|
+
Renormalize3((resh),(resm),(resl),_rec_t21,_rec_t22,_rec_t23); \
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
|
1379
|
+
|
1380
|
+
#endif /*TRIPLE_rec_DOUBLE_rec_H*/
|