crmf 0.1.1 → 0.1.3

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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -0
  3. data/crmf.gemspec +105 -3
  4. data/ext/crlibm-1.0beta5/AUTHORS +2 -0
  5. data/ext/crlibm-1.0beta5/CMakeLists.txt +154 -0
  6. data/ext/crlibm-1.0beta5/COPYING +340 -0
  7. data/ext/crlibm-1.0beta5/COPYING.LIB +504 -0
  8. data/ext/crlibm-1.0beta5/ChangeLog +125 -0
  9. data/ext/crlibm-1.0beta5/Makefile.am +134 -0
  10. data/ext/crlibm-1.0beta5/NEWS +0 -0
  11. data/ext/crlibm-1.0beta5/README +31 -0
  12. data/ext/crlibm-1.0beta5/README.DEV +23 -0
  13. data/ext/crlibm-1.0beta5/README.md +5 -0
  14. data/ext/crlibm-1.0beta5/TODO +66 -0
  15. data/ext/crlibm-1.0beta5/VERSION +1 -0
  16. data/ext/crlibm-1.0beta5/acos-td.c +1195 -0
  17. data/ext/crlibm-1.0beta5/acos-td.h +629 -0
  18. data/ext/crlibm-1.0beta5/asin-td.c +1297 -0
  19. data/ext/crlibm-1.0beta5/asin-td.h +620 -0
  20. data/ext/crlibm-1.0beta5/asincos.c +4488 -0
  21. data/ext/crlibm-1.0beta5/asincos.h +575 -0
  22. data/ext/crlibm-1.0beta5/atan-itanium.c +846 -0
  23. data/ext/crlibm-1.0beta5/atan-pentium.c +280 -0
  24. data/ext/crlibm-1.0beta5/atan-pentium.h +343 -0
  25. data/ext/crlibm-1.0beta5/atan_accurate.c +341 -0
  26. data/ext/crlibm-1.0beta5/atan_accurate.h +198 -0
  27. data/ext/crlibm-1.0beta5/atan_fast.c +506 -0
  28. data/ext/crlibm-1.0beta5/atan_fast.h +680 -0
  29. data/ext/crlibm-1.0beta5/configure.ac +419 -0
  30. data/ext/crlibm-1.0beta5/crlibm.h +204 -0
  31. data/ext/crlibm-1.0beta5/crlibm.spec +42 -0
  32. data/ext/crlibm-1.0beta5/crlibm_private.c +397 -0
  33. data/ext/crlibm-1.0beta5/crlibm_private.h +1048 -0
  34. data/ext/crlibm-1.0beta5/csh_fast.c +721 -0
  35. data/ext/crlibm-1.0beta5/csh_fast.h +771 -0
  36. data/ext/crlibm-1.0beta5/double-extended.h +496 -0
  37. data/ext/crlibm-1.0beta5/exp-itanium.c +723 -0
  38. data/ext/crlibm-1.0beta5/exp-td-standalone.c +87 -0
  39. data/ext/crlibm-1.0beta5/exp-td.c +1363 -0
  40. data/ext/crlibm-1.0beta5/exp-td.h +685 -0
  41. data/ext/crlibm-1.0beta5/exp_build_coeffs/exp_fast_table.c +125 -0
  42. data/ext/crlibm-1.0beta5/expm1-standalone.c +119 -0
  43. data/ext/crlibm-1.0beta5/expm1.c +2515 -0
  44. data/ext/crlibm-1.0beta5/expm1.h +715 -0
  45. data/ext/crlibm-1.0beta5/interval.h +238 -0
  46. data/ext/crlibm-1.0beta5/log-de.c +480 -0
  47. data/ext/crlibm-1.0beta5/log-de.h +747 -0
  48. data/ext/crlibm-1.0beta5/log-de2.c +280 -0
  49. data/ext/crlibm-1.0beta5/log-de2.h +2352 -0
  50. data/ext/crlibm-1.0beta5/log-td.c +1158 -0
  51. data/ext/crlibm-1.0beta5/log-td.h +819 -0
  52. data/ext/crlibm-1.0beta5/log.c +2244 -0
  53. data/ext/crlibm-1.0beta5/log.h +1592 -0
  54. data/ext/crlibm-1.0beta5/log10-td.c +906 -0
  55. data/ext/crlibm-1.0beta5/log10-td.h +823 -0
  56. data/ext/crlibm-1.0beta5/log1p.c +1295 -0
  57. data/ext/crlibm-1.0beta5/log2-td.c +1521 -0
  58. data/ext/crlibm-1.0beta5/log2-td.h +821 -0
  59. data/ext/crlibm-1.0beta5/log2_accurate.c +330 -0
  60. data/ext/crlibm-1.0beta5/log2_accurate.h +261 -0
  61. data/ext/crlibm-1.0beta5/log_accurate.c +133 -0
  62. data/ext/crlibm-1.0beta5/log_accurate.h +261 -0
  63. data/ext/crlibm-1.0beta5/log_fast.c +360 -0
  64. data/ext/crlibm-1.0beta5/log_fast.h +440 -0
  65. data/ext/crlibm-1.0beta5/pow.c +1396 -0
  66. data/ext/crlibm-1.0beta5/pow.h +3101 -0
  67. data/ext/crlibm-1.0beta5/prepare +20 -0
  68. data/ext/crlibm-1.0beta5/rem_pio2_accurate.c +219 -0
  69. data/ext/crlibm-1.0beta5/rem_pio2_accurate.h +53 -0
  70. data/ext/crlibm-1.0beta5/scs_lib/AUTHORS +3 -0
  71. data/ext/crlibm-1.0beta5/scs_lib/COPYING +504 -0
  72. data/ext/crlibm-1.0beta5/scs_lib/ChangeLog +16 -0
  73. data/ext/crlibm-1.0beta5/scs_lib/Doxyfile.dev +939 -0
  74. data/ext/crlibm-1.0beta5/scs_lib/Doxyfile.user +939 -0
  75. data/ext/crlibm-1.0beta5/scs_lib/INSTALL +215 -0
  76. data/ext/crlibm-1.0beta5/scs_lib/Makefile.am +17 -0
  77. data/ext/crlibm-1.0beta5/scs_lib/NEWS +0 -0
  78. data/ext/crlibm-1.0beta5/scs_lib/README +9 -0
  79. data/ext/crlibm-1.0beta5/scs_lib/README.DEV +38 -0
  80. data/ext/crlibm-1.0beta5/scs_lib/TODO +4 -0
  81. data/ext/crlibm-1.0beta5/scs_lib/VERSION +1 -0
  82. data/ext/crlibm-1.0beta5/scs_lib/addition_scs.c +623 -0
  83. data/ext/crlibm-1.0beta5/scs_lib/division_scs.c +110 -0
  84. data/ext/crlibm-1.0beta5/scs_lib/double2scs.c +174 -0
  85. data/ext/crlibm-1.0beta5/scs_lib/main.dox +104 -0
  86. data/ext/crlibm-1.0beta5/scs_lib/multiplication_scs.c +339 -0
  87. data/ext/crlibm-1.0beta5/scs_lib/poly_fct.c +112 -0
  88. data/ext/crlibm-1.0beta5/scs_lib/print_scs.c +73 -0
  89. data/ext/crlibm-1.0beta5/scs_lib/rand_scs.c +63 -0
  90. data/ext/crlibm-1.0beta5/scs_lib/scs.h +353 -0
  91. data/ext/crlibm-1.0beta5/scs_lib/scs2double.c +411 -0
  92. data/ext/crlibm-1.0beta5/scs_lib/scs2mpf.c +58 -0
  93. data/ext/crlibm-1.0beta5/scs_lib/scs2mpfr.c +61 -0
  94. data/ext/crlibm-1.0beta5/scs_lib/scs_private.c +23 -0
  95. data/ext/crlibm-1.0beta5/scs_lib/scs_private.h +133 -0
  96. data/ext/crlibm-1.0beta5/scs_lib/wrapper_scs.h +486 -0
  97. data/ext/crlibm-1.0beta5/scs_lib/zero_scs.c +52 -0
  98. data/ext/crlibm-1.0beta5/trigo_accurate.c +501 -0
  99. data/ext/crlibm-1.0beta5/trigo_accurate.h +331 -0
  100. data/ext/crlibm-1.0beta5/trigo_fast.c +1243 -0
  101. data/ext/crlibm-1.0beta5/trigo_fast.h +639 -0
  102. data/ext/crlibm-1.0beta5/trigpi.c +1169 -0
  103. data/ext/crlibm-1.0beta5/trigpi.h +556 -0
  104. data/ext/crlibm-1.0beta5/triple-double.c +57 -0
  105. data/ext/crlibm-1.0beta5/triple-double.h +1380 -0
  106. data/ext/crmf/crmf.c +117 -20
  107. data/ext/crmf/extconf.rb +12 -8
  108. data/lib/crmf/version.rb +1 -1
  109. data/tests/perf.rb +100 -219
  110. metadata +108 -10
  111. 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 */