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,411 @@
|
|
1
|
+
/** Conversion of SCS to floating-point double
|
2
|
+
@file scs2double.c
|
3
|
+
|
4
|
+
@author Defour David David.Defour@ens-lyon.fr
|
5
|
+
@author Florent de Dinechin Florent.de.Dinechin@ens-lyon.fr
|
6
|
+
|
7
|
+
This file is part of the SCS library.
|
8
|
+
*/
|
9
|
+
|
10
|
+
/*
|
11
|
+
Copyright (C) 2002 David Defour and Florent de Dinechin
|
12
|
+
|
13
|
+
This library is free software; you can redistribute it and/or
|
14
|
+
modify it under the terms of the GNU Lesser General Public
|
15
|
+
License as published by the Free Software Foundation; either
|
16
|
+
version 2.1 of the License, or (at your option) any later version.
|
17
|
+
|
18
|
+
This library is distributed in the hope that it will be useful,
|
19
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
21
|
+
Lesser General Public License for more details.
|
22
|
+
|
23
|
+
You should have received a copy of the GNU Lesser General Public
|
24
|
+
License along with this library; if not, write to the Free Software
|
25
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
26
|
+
|
27
|
+
*/
|
28
|
+
#include "scs.h"
|
29
|
+
#include "scs_private.h"
|
30
|
+
|
31
|
+
|
32
|
+
/** Convert a multiple precision number in scs format into a double
|
33
|
+
precision number.
|
34
|
+
|
35
|
+
@warning "x" need to be normalized
|
36
|
+
*/
|
37
|
+
|
38
|
+
/* TODO BUG scs_get_d doesn't do round-to nearest even */
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
/* computes the exponent from the index */
|
44
|
+
/* in principle an inline function would be cleaner, but
|
45
|
+
this leads to faster and smaller code
|
46
|
+
*/
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
void scs_get_d(double *result, scs_ptr x){
|
53
|
+
db_number nb, rndcorr;
|
54
|
+
uint64_t lowpart, roundbits, t1;
|
55
|
+
int expo, expofinal, shift;
|
56
|
+
double res;
|
57
|
+
|
58
|
+
/* convert the MSB digit into a double, and store it in nb.d */
|
59
|
+
nb.d = (double)X_HW[0];
|
60
|
+
|
61
|
+
/* place the two next digits in lowpart */
|
62
|
+
t1 = X_HW[1];
|
63
|
+
lowpart = (t1 << SCS_NB_BITS) + X_HW[2];
|
64
|
+
/* there is at least one significant bit in nb,
|
65
|
+
and at least 2*SCS_NB_BITS in lowpart,
|
66
|
+
so provided SCS_NB_BITS >= 27
|
67
|
+
together they include the 53+ guard bits to decide rounding
|
68
|
+
*/
|
69
|
+
|
70
|
+
/* test for s/qNan, +/- Inf, +/- 0, placed here for obscure performance reasons */
|
71
|
+
if (X_EXP != 1){
|
72
|
+
*result = X_EXP;
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
|
76
|
+
/* take the exponent of nb.d (will be in [0:SCS_NB_BITS])*/
|
77
|
+
expo = ((nb.i[HI] & 0x7ff00000)>>20) - 1023;
|
78
|
+
|
79
|
+
/* compute the exponent of the result */
|
80
|
+
expofinal = expo + SCS_NB_BITS*X_IND;
|
81
|
+
|
82
|
+
/* Is the SCS number not too large for the IEEE exponent range ? */
|
83
|
+
if (expofinal > 1023) {
|
84
|
+
/* return an infinity */
|
85
|
+
res = SCS_RADIX_RNG_DOUBLE*SCS_RADIX_RNG_DOUBLE;
|
86
|
+
}
|
87
|
+
|
88
|
+
/* Is our SCS number a denormal ? */
|
89
|
+
else if (expofinal >= -1022){
|
90
|
+
/* x is in the normal range */
|
91
|
+
shift=expo+2*SCS_NB_BITS-53;
|
92
|
+
roundbits=lowpart<<(64-shift);
|
93
|
+
/* align the rest of the mantissa to nb : shift by (2*SCS_NB_BITS)-53+expo */
|
94
|
+
lowpart = lowpart >> shift;
|
95
|
+
/* Look at the last bit to decide rounding */
|
96
|
+
|
97
|
+
if (lowpart & ULL(0000000000000001)){
|
98
|
+
/* Test for the round to even case */
|
99
|
+
if(roundbits==0)
|
100
|
+
{ int i;
|
101
|
+
for (i=3; i<SCS_NB_WORDS; i++)
|
102
|
+
roundbits=roundbits | X_HW[i];
|
103
|
+
}
|
104
|
+
if(roundbits==0) {
|
105
|
+
/* round to even mantissa */
|
106
|
+
if (lowpart & ULL(0000000000000002)){
|
107
|
+
/* mantissa odd, need to add an half-ulp */
|
108
|
+
rndcorr.i[LO] = 0;
|
109
|
+
rndcorr.i[HI] = (expo-52+1023)<<20; /* 2^(exp-52) */
|
110
|
+
}else
|
111
|
+
rndcorr.d = 0.0;
|
112
|
+
}
|
113
|
+
else { /* there are round bits need to add an half-ulp */
|
114
|
+
rndcorr.i[LO] = 0;
|
115
|
+
rndcorr.i[HI] = (expo-52+1023)<<20; /* 2^(exp-52) */
|
116
|
+
}
|
117
|
+
}else{
|
118
|
+
/* need to add nothing*/
|
119
|
+
rndcorr.d = 0.0;
|
120
|
+
}
|
121
|
+
|
122
|
+
lowpart = lowpart >> 1;
|
123
|
+
nb.l = nb.l | lowpart; /* Finish to fill the mantissa */
|
124
|
+
res = nb.d + rndcorr.d; /* rounded to nearest */
|
125
|
+
|
126
|
+
/* now compute the exponent from the index :
|
127
|
+
we need to multiply res by 2^(X_IND*SCS_NB_BITS)
|
128
|
+
First check this number won't be a denormal itself */
|
129
|
+
if((X_IND)*SCS_NB_BITS +1023 > 0) {
|
130
|
+
/* build the double 2^(X_IND*SCS_NB_BITS) */
|
131
|
+
nb.i[HI] = ((X_IND)*SCS_NB_BITS +1023) << 20;
|
132
|
+
nb.i[LO] = 0;
|
133
|
+
res *= nb.d; /* exact multiplication */
|
134
|
+
}
|
135
|
+
else { /*offset the previous computation by 2^(2*SCS_NB_BITS) */
|
136
|
+
/* build the double 2^(X_IND*SCS_NB_BITS) */
|
137
|
+
nb.i[HI] = ((X_IND)*SCS_NB_BITS +1023 + 2*SCS_NB_BITS) << 20;
|
138
|
+
nb.i[LO] = 0;
|
139
|
+
res *= SCS_RADIX_MTWO_DOUBLE; /* exact multiplication */
|
140
|
+
res *= nb.d; /* exact multiplication */
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
else {
|
146
|
+
/* the final number is a denormal with 52-(expfinal+1022)
|
147
|
+
significant bits. */
|
148
|
+
|
149
|
+
if (expofinal < -1022 - 53 ) {
|
150
|
+
res = 0.0;
|
151
|
+
}
|
152
|
+
else {
|
153
|
+
|
154
|
+
/* align the rest of the mantissa to nb */
|
155
|
+
lowpart = lowpart >> (expo+(2*SCS_NB_BITS)-52);
|
156
|
+
/* Finish to fill the mantissa */
|
157
|
+
nb.l = nb.l | lowpart;
|
158
|
+
|
159
|
+
/* this is still a normal number.
|
160
|
+
Now remove its exponent and add back the implicit one */
|
161
|
+
nb.l = (nb.l & ULL(000FFFFFFFFFFFFF)) | ULL(0010000000000000);
|
162
|
+
|
163
|
+
/* keep only the significant bits */
|
164
|
+
nb.l = nb.l >> (-1023 - expofinal);
|
165
|
+
/* Look at the last bit to decide rounding */
|
166
|
+
if (nb.i[LO] & 0x00000001){
|
167
|
+
/* need to add an half-ulp */
|
168
|
+
rndcorr.l = 1; /* this is a full ulp but we multiply by 0.5 in the end */
|
169
|
+
}else{
|
170
|
+
/* need to add nothing*/
|
171
|
+
rndcorr.d = 0.0;
|
172
|
+
|
173
|
+
}
|
174
|
+
res = 0.5*(nb.d + rndcorr.d); /* rounded to nearest */
|
175
|
+
|
176
|
+
/* the exponent field is already set to zero so that's all */
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
/* sign management */
|
181
|
+
if (X_SGN < 0)
|
182
|
+
*result = - res;
|
183
|
+
else
|
184
|
+
*result = res;
|
185
|
+
}
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
/* All the directed roundings boil down to the same computation, which
|
192
|
+
is: first build the truncated mantissa. if the SCS number is exactly
|
193
|
+
a double precision number, return that. Otherwise, either return the
|
194
|
+
truncated mantissa, or return this mantissa plus an ulp, rounded to
|
195
|
+
the nearest. Plus handle the infinities and denormals.
|
196
|
+
*/
|
197
|
+
|
198
|
+
static void get_d_directed(double *result, scs_ptr x, int rndMantissaUp){
|
199
|
+
db_number nb, rndcorr;
|
200
|
+
uint64_t lowpart, t1;
|
201
|
+
int expo,expofinal,i, not_null;
|
202
|
+
double res;
|
203
|
+
|
204
|
+
/* convert the MSB digit into a double, and store it in nb.d */
|
205
|
+
nb.d = (double)X_HW[0];
|
206
|
+
|
207
|
+
/* place the two next digits in lowpart */
|
208
|
+
t1 = X_HW[1];
|
209
|
+
lowpart = (t1 << SCS_NB_BITS) + X_HW[2];
|
210
|
+
|
211
|
+
/* test for s/qNan, +/- Inf, +/- 0, placed here for obscure performance reasons */
|
212
|
+
if (X_EXP != 1){
|
213
|
+
*result = X_EXP;
|
214
|
+
return;
|
215
|
+
}
|
216
|
+
|
217
|
+
/* take the exponent of nb.d (will be in [0:SCS_NB_BITS])*/
|
218
|
+
expo = ((nb.i[HI] & 0x7ff00000)>>20) - 1023;
|
219
|
+
not_null = ((lowpart << (64+52 - 2*SCS_NB_BITS - expo)) != 0 );
|
220
|
+
/* Test if we are not on an exact double precision number */
|
221
|
+
for (i=3; i<SCS_NB_WORDS; i++)
|
222
|
+
if (X_HW[i]!=0) not_null = 1;
|
223
|
+
|
224
|
+
/* compute the exponent of the result */
|
225
|
+
expofinal = expo + SCS_NB_BITS*X_IND;
|
226
|
+
|
227
|
+
/* Is the SCS number not too large for the IEEE exponent range ? */
|
228
|
+
if (expofinal > 1023) {
|
229
|
+
if (rndMantissaUp)
|
230
|
+
/* return an infinity */
|
231
|
+
res = SCS_RADIX_RNG_DOUBLE*SCS_RADIX_RNG_DOUBLE;
|
232
|
+
else
|
233
|
+
/* infinity, rounded down, is SCS_MAX_DOUBLE */
|
234
|
+
res = SCS_MAX_DOUBLE;
|
235
|
+
}
|
236
|
+
|
237
|
+
/* Is our SCS number a denormal ? */
|
238
|
+
else if (expofinal >= -1022){
|
239
|
+
/* x is in the normal range */
|
240
|
+
|
241
|
+
/* align the rest of the mantissa to nb : shift by (2*SCS_NB_BITS)-53-exp */
|
242
|
+
lowpart = lowpart >> (expo+(2*SCS_NB_BITS)-52);
|
243
|
+
/* Finish to fill the mantissa */
|
244
|
+
nb.l = nb.l | lowpart;
|
245
|
+
if (rndMantissaUp && (not_null)){
|
246
|
+
rndcorr.i[LO] = 0;
|
247
|
+
rndcorr.i[HI] = (expo-52+1023)<<20; /* 2^(exp-52) */
|
248
|
+
} else {
|
249
|
+
rndcorr.d = 0.0;
|
250
|
+
}
|
251
|
+
res = nb.d + rndcorr.d; /* rounded to nearest */
|
252
|
+
|
253
|
+
/* now compute the exponent from the index :
|
254
|
+
we need to multiply res by 2^(X_IND*SCS_NB_BITS)
|
255
|
+
First check this number won't be a denormal itself */
|
256
|
+
if((X_IND)*SCS_NB_BITS +1023 > 0) {
|
257
|
+
/* build the double 2^(X_IND*SCS_NB_BITS) */
|
258
|
+
nb.i[HI] = ((X_IND)*SCS_NB_BITS +1023) << 20;
|
259
|
+
nb.i[LO] = 0;
|
260
|
+
res *= nb.d; /* exact multiplication */
|
261
|
+
}
|
262
|
+
else { /*offset the previous computation by 2^(2*SCS_NB_BITS) */
|
263
|
+
/* build the double 2^(X_IND*SCS_NB_BITS) */
|
264
|
+
nb.i[HI] = ((X_IND)*SCS_NB_BITS +1023 + 2*SCS_NB_BITS) << 20;
|
265
|
+
nb.i[LO] = 0;
|
266
|
+
res *= SCS_RADIX_MTWO_DOUBLE; /* exact multiplication */
|
267
|
+
res *= nb.d; /* exact multiplication */
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
|
272
|
+
else {
|
273
|
+
/* the final number is a denormal with 52-(expfinal+1022)
|
274
|
+
significant bits. */
|
275
|
+
|
276
|
+
if (expofinal < -1022 - 53 ) {
|
277
|
+
if(rndMantissaUp)
|
278
|
+
res = SCS_MIN_DOUBLE;
|
279
|
+
else
|
280
|
+
res = 0.0;
|
281
|
+
}
|
282
|
+
else {
|
283
|
+
|
284
|
+
/* align the rest of the mantissa to nb */
|
285
|
+
lowpart = lowpart >> (expo+(2*SCS_NB_BITS)-52);
|
286
|
+
/* Finish to fill the mantissa */
|
287
|
+
nb.l = nb.l | lowpart;
|
288
|
+
|
289
|
+
/* this is still a normal number.
|
290
|
+
Now remove its exponent and add back the implicit one */
|
291
|
+
nb.l = (nb.l & ULL(000FFFFFFFFFFFFF)) | ULL(0010000000000000);
|
292
|
+
|
293
|
+
if (rndMantissaUp && (not_null)){
|
294
|
+
nb.l = nb.l >> (-1022 - expofinal);
|
295
|
+
nb.l = nb.l +1; /* works even if we move back into the normals*/
|
296
|
+
}
|
297
|
+
else
|
298
|
+
/* keep only the significant bits */
|
299
|
+
nb.l = nb.l >> (-1022 - expofinal);
|
300
|
+
|
301
|
+
res = nb.d;
|
302
|
+
|
303
|
+
/* the exponent field is already set to zero so that's all */
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
/* sign management */
|
308
|
+
if (X_SGN < 0)
|
309
|
+
*result = - res;
|
310
|
+
else
|
311
|
+
*result = res;
|
312
|
+
}
|
313
|
+
|
314
|
+
#if 0
|
315
|
+
void get_d_directed0(double *result, scs_ptr x,int rndMantissaUp)
|
316
|
+
{
|
317
|
+
uint64_t lowpart, t1;
|
318
|
+
db_number nb, rndcorr;
|
319
|
+
int i, expo, not_null;
|
320
|
+
double res;
|
321
|
+
/* convert the MSB digit into a double, and store it in nb.d */
|
322
|
+
nb.d = (double)X_HW[0];
|
323
|
+
/* place the two next digits in lowpart */
|
324
|
+
t1 = X_HW[1];
|
325
|
+
lowpart = (t1 << SCS_NB_BITS) + X_HW[2];
|
326
|
+
/* s/qNan, +/- Inf, +/- 0 */
|
327
|
+
if (X_EXP != 1){
|
328
|
+
*result = X_EXP;
|
329
|
+
return;
|
330
|
+
}
|
331
|
+
/* take the exponent */
|
332
|
+
expo = ((nb.i[HI] & 0x7ff00000)>>20) - 1023;
|
333
|
+
not_null = ((lowpart << (64+52 - 2*SCS_NB_BITS - expo)) != 0 );
|
334
|
+
/* align the rest of the mantissa */
|
335
|
+
lowpart = lowpart >> (expo + 2*SCS_NB_BITS - 52);
|
336
|
+
/* Finish to fill the mantissa */
|
337
|
+
nb.l = nb.l | lowpart;
|
338
|
+
/* Test if we are not on an exact double precision number */
|
339
|
+
for (i=3; i<SCS_NB_WORDS; i++)
|
340
|
+
if (X_HW[i]!=0) not_null = 1;
|
341
|
+
if (rndMantissaUp && (not_null)){
|
342
|
+
rndcorr.i[LO] = 0;
|
343
|
+
rndcorr.i[HI] = (expo-52+1023)<<20; /* 2^(exp-52) */
|
344
|
+
} else {
|
345
|
+
rndcorr.d = 0.0;
|
346
|
+
}
|
347
|
+
res = nb.d + rndcorr.d; /* make a rounded to nearest */
|
348
|
+
if ((X_IND < SCS_MAX_RANGE) && (X_IND > -SCS_MAX_RANGE)){
|
349
|
+
/* x is comfortably in the double-precision range */
|
350
|
+
/* build the double 2^(X_IND*SCS_NB_BITS) */
|
351
|
+
nb.i[HI] = ((X_IND)*SCS_NB_BITS +1023) << 20;
|
352
|
+
nb.i[LO] = 0;
|
353
|
+
res *= nb.d;
|
354
|
+
}else {
|
355
|
+
/* x may end up being a denormal or overflow */
|
356
|
+
i = X_IND;
|
357
|
+
nb.d = 0;
|
358
|
+
if (X_IND > 0){
|
359
|
+
/* one of the following computations may lead to an overflow */
|
360
|
+
res *=SCS_RADIX_RNG_DOUBLE; /* 2^(SCS_NB_BITS.SCS_MAX_RANGE) */
|
361
|
+
i -= SCS_MAX_RANGE;
|
362
|
+
while((i-->0)&&(res <= SCS_MAX_DOUBLE)) {
|
363
|
+
/* second test means: This loop stops on overflow */
|
364
|
+
res *= SCS_RADIX_ONE_DOUBLE;
|
365
|
+
}
|
366
|
+
}else {
|
367
|
+
/* One of the computations may lead to denormal/underflow */
|
368
|
+
res *=SCS_RADIX_MRNG_DOUBLE; /* 2^-(SCS_NB_BITS.SCS_MAX_RANGE)*/
|
369
|
+
i += SCS_MAX_RANGE;
|
370
|
+
while((i++<0)&&(res != 0)) {
|
371
|
+
res *=SCS_RADIX_MONE_DOUBLE;
|
372
|
+
}
|
373
|
+
}
|
374
|
+
}
|
375
|
+
/* sign management */
|
376
|
+
if (X_SGN < 0)
|
377
|
+
*result = - res;
|
378
|
+
else
|
379
|
+
*result = res;
|
380
|
+
}
|
381
|
+
|
382
|
+
#endif
|
383
|
+
/*
|
384
|
+
* Rounded toward -Inf
|
385
|
+
*/
|
386
|
+
void scs_get_d_minf(double *result, scs_ptr x){
|
387
|
+
|
388
|
+
/* round up the mantissa if negative */
|
389
|
+
get_d_directed(result, x, (int)(X_SGN<0));
|
390
|
+
}
|
391
|
+
|
392
|
+
|
393
|
+
|
394
|
+
/*
|
395
|
+
* Rounded toward +Inf
|
396
|
+
*/
|
397
|
+
void scs_get_d_pinf(double *result, scs_ptr x){
|
398
|
+
|
399
|
+
/* round up the mantissa if positive */
|
400
|
+
get_d_directed(result, x, (int)(X_SGN>=0));
|
401
|
+
}
|
402
|
+
|
403
|
+
|
404
|
+
|
405
|
+
/*
|
406
|
+
* Rounded toward zero
|
407
|
+
*/
|
408
|
+
void scs_get_d_zero(double *result, scs_ptr x){
|
409
|
+
/* never round up the mantissa */
|
410
|
+
get_d_directed(result, x, 0);
|
411
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/*
|
2
|
+
* Author : Defour David
|
3
|
+
* Contact : David.Defour@ens-lyon.fr
|
4
|
+
*
|
5
|
+
* This program is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
* the Free Software Foundation; either version 2 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU Lesser General Public License
|
16
|
+
* along with this program; if not, write to the Free Software
|
17
|
+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
18
|
+
*/
|
19
|
+
|
20
|
+
|
21
|
+
#include "scs.h"
|
22
|
+
#include "scs_private.h"
|
23
|
+
|
24
|
+
/* Compile only if gmp is present */
|
25
|
+
|
26
|
+
#ifdef HAVE_GMP_H
|
27
|
+
|
28
|
+
/*
|
29
|
+
* Convert a scs number into a MPF number (GMP)
|
30
|
+
*/
|
31
|
+
void scs_get_mpf(scs_ptr x, mpf_t rop){
|
32
|
+
mpf_t mp1;
|
33
|
+
long int expo;
|
34
|
+
int i;
|
35
|
+
|
36
|
+
mpf_set_ui(rop, 0);
|
37
|
+
|
38
|
+
/* mantissa */
|
39
|
+
for (i=0; i<SCS_NB_WORDS; i++){
|
40
|
+
mpf_mul_2exp(rop, rop, SCS_NB_BITS);
|
41
|
+
mpf_add_ui(rop, rop, X_HW[i]);
|
42
|
+
}
|
43
|
+
|
44
|
+
/* sign */
|
45
|
+
if (X_SGN == -1) mpf_neg(rop, rop);
|
46
|
+
|
47
|
+
/* exception */
|
48
|
+
mpf_init_set_d(mp1, X_EXP); mpf_mul(rop, rop, mp1);
|
49
|
+
|
50
|
+
/* exponent */
|
51
|
+
expo = (X_IND - SCS_NB_WORDS + 1) * SCS_NB_BITS;
|
52
|
+
|
53
|
+
if (expo < 0) mpf_div_2exp(rop, rop, (unsigned int) -expo);
|
54
|
+
else mpf_mul_2exp(rop, rop, (unsigned int) expo);
|
55
|
+
|
56
|
+
mpf_clear(mp1);
|
57
|
+
}
|
58
|
+
#endif /*HAVE_GMP_H*/
|
@@ -0,0 +1,61 @@
|
|
1
|
+
/*
|
2
|
+
* Author : Defour David
|
3
|
+
* Contact : David.Defour@ens-lyon.fr
|
4
|
+
*
|
5
|
+
* This program is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
* the Free Software Foundation; either version 2 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU Lesser General Public License
|
16
|
+
* along with this program; if not, write to the Free Software
|
17
|
+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
18
|
+
*/
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
#include "scs.h"
|
23
|
+
#include "scs_private.h"
|
24
|
+
|
25
|
+
/* Compile only if mpfr is present */
|
26
|
+
|
27
|
+
#ifdef HAVE_MPFR_H
|
28
|
+
|
29
|
+
|
30
|
+
/*
|
31
|
+
* Convert a scs number into a MPFR number rounded to nearest
|
32
|
+
*/
|
33
|
+
void scs_get_mpfr(scs_ptr x, mpfr_t rop){
|
34
|
+
mpfr_t mp1;
|
35
|
+
long int expo;
|
36
|
+
int i;
|
37
|
+
|
38
|
+
mpfr_set_ui(rop, 0, GMP_RNDN);
|
39
|
+
|
40
|
+
/* mantissa */
|
41
|
+
for (i=0; i<SCS_NB_WORDS; i++){
|
42
|
+
mpfr_mul_2exp(rop, rop, SCS_NB_BITS, GMP_RNDN);
|
43
|
+
mpfr_add_ui(rop, rop, X_HW[i], GMP_RNDN);
|
44
|
+
}
|
45
|
+
|
46
|
+
/* sign */
|
47
|
+
if (X_SGN == -1) mpfr_neg(rop, rop, GMP_RNDN);
|
48
|
+
|
49
|
+
/* exception */
|
50
|
+
mpfr_init_set_d(mp1, X_EXP, GMP_RNDN);
|
51
|
+
mpfr_mul(rop, rop, mp1, GMP_RNDN);
|
52
|
+
|
53
|
+
/* exponent */
|
54
|
+
expo = (X_IND - SCS_NB_WORDS + 1) * SCS_NB_BITS;
|
55
|
+
|
56
|
+
if (expo < 0) mpfr_div_2exp(rop, rop, (unsigned int) -expo, GMP_RNDN);
|
57
|
+
else mpfr_mul_2exp(rop, rop, (unsigned int) expo, GMP_RNDN);
|
58
|
+
|
59
|
+
mpfr_clear(mp1);
|
60
|
+
}
|
61
|
+
#endif /* HAVE_MPFR_H */
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#include "scs.h"
|
2
|
+
#include "scs_private.h"
|
3
|
+
|
4
|
+
#ifdef WORDS_BIGENDIAN
|
5
|
+
const db_number radix_one_double = {{((1023+SCS_NB_BITS)<<20) , 0x00000000 }};
|
6
|
+
const db_number radix_two_double = {{((1023+2*SCS_NB_BITS)<<20) , 0x00000000 }};
|
7
|
+
const db_number radix_mone_double = {{((1023-SCS_NB_BITS)<<20) , 0x00000000 }};
|
8
|
+
const db_number radix_mtwo_double = {{((1023-2*SCS_NB_BITS)<<20) , 0x00000000 }};
|
9
|
+
const db_number radix_rng_double = {{((1023+SCS_NB_BITS*SCS_MAX_RANGE)<<20) , 0x00000000 }};
|
10
|
+
const db_number radix_mrng_double = {{((1023-SCS_NB_BITS*SCS_MAX_RANGE)<<20) , 0x00000000 }};
|
11
|
+
const db_number max_double = {{0x7FEFFFFF , 0xFFFFFFFF }};
|
12
|
+
const db_number min_double = {{0x00000000 , 0x00000001 }};
|
13
|
+
#else
|
14
|
+
const db_number radix_one_double = {{0x00000000 , ((1023+SCS_NB_BITS)<<20) }};
|
15
|
+
const db_number radix_two_double = {{0x00000000 , ((1023+2*SCS_NB_BITS)<<20) }};
|
16
|
+
const db_number radix_mone_double = {{0x00000000 , ((1023-SCS_NB_BITS)<<20) }};
|
17
|
+
const db_number radix_mtwo_double = {{0x00000000 , ((1023-2*SCS_NB_BITS)<<20) }};
|
18
|
+
const db_number radix_rng_double = {{0x00000000 , ((1023+SCS_NB_BITS*SCS_MAX_RANGE)<<20) }};
|
19
|
+
const db_number radix_mrng_double = {{0x00000000 , ((1023-SCS_NB_BITS*SCS_MAX_RANGE)<<20) }};
|
20
|
+
const db_number max_double = {{0xFFFFFFFF , 0x7FEFFFFF }};
|
21
|
+
const db_number min_double = {{0x00000001 , 0x00000000 }};
|
22
|
+
#endif
|
23
|
+
|
@@ -0,0 +1,133 @@
|
|
1
|
+
/** Various declarations and macros shared by
|
2
|
+
several .c files, but useless to users of the library
|
3
|
+
|
4
|
+
@file scs_private.h
|
5
|
+
|
6
|
+
@author Defour David David.Defour@ens-lyon.fr
|
7
|
+
@author Florent de Dinechin Florent.de.Dinechin@ens-lyon.fr
|
8
|
+
*/
|
9
|
+
|
10
|
+
|
11
|
+
/*
|
12
|
+
Copyright (C) 2002 David Defour and Florent de Dinechin
|
13
|
+
|
14
|
+
This library is free software; you can redistribute it and/or
|
15
|
+
modify it under the terms of the GNU Lesser General Public
|
16
|
+
License as published by the Free Software Foundation; either
|
17
|
+
version 2.1 of the License, or (at your option) any later version.
|
18
|
+
|
19
|
+
This library is distributed in the hope that it will be useful,
|
20
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
21
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
22
|
+
Lesser General Public License for more details.
|
23
|
+
|
24
|
+
You should have received a copy of the GNU Lesser General Public
|
25
|
+
License along with this library; if not, write to the Free Software
|
26
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
27
|
+
|
28
|
+
*/
|
29
|
+
#ifndef SCS_PRIVATE_H
|
30
|
+
#define SCS_PRIVATE_H 1
|
31
|
+
|
32
|
+
|
33
|
+
#define SCS_RADIX ((unsigned int)(1<<SCS_NB_BITS))
|
34
|
+
|
35
|
+
#define SCS_MASK_RADIX ((unsigned int)(SCS_RADIX-1))
|
36
|
+
|
37
|
+
#include "scs.h"
|
38
|
+
|
39
|
+
#ifdef WORDS_BIGENDIAN
|
40
|
+
#define HI 0
|
41
|
+
#define LO 1
|
42
|
+
#else
|
43
|
+
#define HI 1
|
44
|
+
#define LO 0
|
45
|
+
#endif
|
46
|
+
|
47
|
+
/* An int such that SCS_MAX_RANGE * SCS_NB_BITS < 1024,
|
48
|
+
where 1024 is the max of the exponent of a double number.
|
49
|
+
Used in scs2double.c along with radix_rng_double et al.
|
50
|
+
The value of 32 is OK for all practical values of SCS_NB_BITS */
|
51
|
+
#define SCS_MAX_RANGE 32
|
52
|
+
|
53
|
+
/*
|
54
|
+
* DEFINITION OF DOUBLE PRECISION FLOATING POINT NUMBER CONSTANTS
|
55
|
+
*/
|
56
|
+
/* In all the following "radix" means 2^(SCS_NB_BITS),
|
57
|
+
and radix_blah means radix^blah.
|
58
|
+
(1023 + e)<<20 is the way to cast e into the exponent field of an IEEE-754 double
|
59
|
+
*/
|
60
|
+
|
61
|
+
|
62
|
+
extern const db_number radix_one_double ;
|
63
|
+
extern const db_number radix_two_double ;
|
64
|
+
extern const db_number radix_mone_double;
|
65
|
+
extern const db_number radix_mtwo_double;
|
66
|
+
extern const db_number radix_rng_double ;
|
67
|
+
extern const db_number radix_mrng_double;
|
68
|
+
extern const db_number max_double ;
|
69
|
+
extern const db_number min_double ;
|
70
|
+
|
71
|
+
|
72
|
+
#define SCS_RADIX_ONE_DOUBLE radix_one_double.d /* 2^(SCS_NB_BITS) */
|
73
|
+
#define SCS_RADIX_TWO_DOUBLE radix_two_double.d /* 2^(2.SCS_NB_BITS) */
|
74
|
+
#define SCS_RADIX_MONE_DOUBLE radix_mone_double.d /* 2^-(SCS_NB_BITS) */
|
75
|
+
#define SCS_RADIX_MTWO_DOUBLE radix_mtwo_double.d /* 2^-(2.SCS_NB_BITS) */
|
76
|
+
#define SCS_RADIX_RNG_DOUBLE radix_rng_double.d /* 2^(SCS_NB_BITS.SCS_MAX_RANGE) */
|
77
|
+
#define SCS_RADIX_MRNG_DOUBLE radix_mrng_double.d /* 2^-(SCS_NB_BITS.SCS_MAX_RANGE)*/
|
78
|
+
#define SCS_MAX_DOUBLE max_double.d /* 2^1024-1 */
|
79
|
+
#define SCS_MIN_DOUBLE min_double.d /* 2^-1074 */
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
#define R_HW result->h_word
|
87
|
+
#define R_SGN result->sign
|
88
|
+
#define R_IND result->index
|
89
|
+
#define R_EXP result->exception.d
|
90
|
+
|
91
|
+
#define X_HW x->h_word
|
92
|
+
#define X_SGN x->sign
|
93
|
+
#define X_IND x->index
|
94
|
+
#define X_EXP x->exception.d
|
95
|
+
|
96
|
+
#define Y_HW y->h_word
|
97
|
+
#define Y_SGN y->sign
|
98
|
+
#define Y_IND y->index
|
99
|
+
#define Y_EXP y->exception.d
|
100
|
+
|
101
|
+
#define Z_HW z->h_word
|
102
|
+
#define Z_SGN z->sign
|
103
|
+
#define Z_IND z->index
|
104
|
+
#define Z_EXP z->exception.d
|
105
|
+
|
106
|
+
#define W_HW w->h_word
|
107
|
+
#define W_SGN w->sign
|
108
|
+
#define W_IND w->index
|
109
|
+
#define W_EXP w->exception.d
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
/* A few additional defines for the case when we use floating-point
|
114
|
+
multiplier (OBSOLETE, NEVER USED ANYMORE but who knows, some day) */
|
115
|
+
|
116
|
+
#ifdef SCS_USE_FLT_MULT
|
117
|
+
/* There is a "53" below, which means that these constants won't do
|
118
|
+
what we expect from them on x86 because of the double extended
|
119
|
+
precision. We could put more ifdefs, but why care, nobody wants to use the
|
120
|
+
FP muls on the x86. */
|
121
|
+
#ifdef WORDS_BIGENDIAN
|
122
|
+
static const db_number scs_flt_trunc_cst = {{ ((1023+SCS_NB_BITS-1)<<20) , 0x00000000 }};
|
123
|
+
static const db_number scs_flt_shift_cst = {{ ((1023+SCS_NB_BITS+53)<<20),0x00000000}};
|
124
|
+
#else
|
125
|
+
static const db_number scs_flt_trunc_cst = {{ 0x00000000, ((1023+SCS_NB_BITS-1)<<20) }};
|
126
|
+
static const db_number scs_flt_shift_cst = {{ 0x00000000 ,((1023+SCS_NB_BITS+53)<<20)}};
|
127
|
+
#endif /*WORDS_BIGENDIAN*/
|
128
|
+
|
129
|
+
#define SCS_FLT_TRUNC_CST scs_flt_trunc_cst.d /* 2^(SCS_NB_BITS+53-1) */
|
130
|
+
#define SCS_FLT_SHIFT_CST scs_flt_shift_cst.d /* 2^(SCS_NB_BITS)(1+1/2) */
|
131
|
+
#endif /* SCS_USE_FLTMULT */
|
132
|
+
|
133
|
+
#endif /* SCS_PRIVATE_H */
|