intervals 0.3.56
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.
- data/VERSION.txt +1 -0
- data/ext/crlibm/AUTHORS +2 -0
- data/ext/crlibm/COPYING +504 -0
- data/ext/crlibm/ChangeLog +80 -0
- data/ext/crlibm/INSTALL +182 -0
- data/ext/crlibm/Makefile.am +84 -0
- data/ext/crlibm/Makefile.in +530 -0
- data/ext/crlibm/NEWS +0 -0
- data/ext/crlibm/README +31 -0
- data/ext/crlibm/TODO +47 -0
- data/ext/crlibm/VERSION +1 -0
- data/ext/crlibm/aclocal.m4 +989 -0
- data/ext/crlibm/atan-itanium.c +846 -0
- data/ext/crlibm/atan-pentium.c +261 -0
- data/ext/crlibm/atan_accurate.c +244 -0
- data/ext/crlibm/atan_accurate.h +191 -0
- data/ext/crlibm/atan_fast.c +324 -0
- data/ext/crlibm/atan_fast.h +678 -0
- data/ext/crlibm/config.guess +1461 -0
- data/ext/crlibm/config.sub +1566 -0
- data/ext/crlibm/configure +7517 -0
- data/ext/crlibm/configure.ac +364 -0
- data/ext/crlibm/crlibm.h +125 -0
- data/ext/crlibm/crlibm_config.h +149 -0
- data/ext/crlibm/crlibm_config.h.in +148 -0
- data/ext/crlibm/crlibm_private.c +293 -0
- data/ext/crlibm/crlibm_private.h +658 -0
- data/ext/crlibm/csh_fast.c +631 -0
- data/ext/crlibm/csh_fast.h +771 -0
- data/ext/crlibm/double-extended.h +496 -0
- data/ext/crlibm/exp-td.c +962 -0
- data/ext/crlibm/exp-td.h +685 -0
- data/ext/crlibm/exp_accurate.c +197 -0
- data/ext/crlibm/exp_accurate.h +85 -0
- data/ext/crlibm/gappa/log-de-E0-logir0.gappa +106 -0
- data/ext/crlibm/gappa/log-de-E0.gappa +79 -0
- data/ext/crlibm/gappa/log-de.gappa +81 -0
- data/ext/crlibm/gappa/log-td-E0-logir0.gappa +126 -0
- data/ext/crlibm/gappa/log-td-E0.gappa +143 -0
- data/ext/crlibm/gappa/log-td-accurate-E0-logir0.gappa +230 -0
- data/ext/crlibm/gappa/log-td-accurate-E0.gappa +213 -0
- data/ext/crlibm/gappa/log-td-accurate.gappa +217 -0
- data/ext/crlibm/gappa/log-td.gappa +156 -0
- data/ext/crlibm/gappa/trigoSinCosCase3.gappa +204 -0
- data/ext/crlibm/gappa/trigoTanCase2.gappa +73 -0
- data/ext/crlibm/install-sh +269 -0
- data/ext/crlibm/log-de.c +431 -0
- data/ext/crlibm/log-de.h +732 -0
- data/ext/crlibm/log-td.c +852 -0
- data/ext/crlibm/log-td.h +819 -0
- data/ext/crlibm/log10-td.c +906 -0
- data/ext/crlibm/log10-td.h +823 -0
- data/ext/crlibm/log2-td.c +935 -0
- data/ext/crlibm/log2-td.h +821 -0
- data/ext/crlibm/maple/atan.mpl +359 -0
- data/ext/crlibm/maple/common-procedures.mpl +997 -0
- data/ext/crlibm/maple/csh.mpl +446 -0
- data/ext/crlibm/maple/double-extended.mpl +151 -0
- data/ext/crlibm/maple/exp-td.mpl +195 -0
- data/ext/crlibm/maple/log-de.mpl +243 -0
- data/ext/crlibm/maple/log-td.mpl +316 -0
- data/ext/crlibm/maple/log10-td.mpl +345 -0
- data/ext/crlibm/maple/log2-td.mpl +334 -0
- data/ext/crlibm/maple/trigo.mpl +728 -0
- data/ext/crlibm/maple/triple-double.mpl +58 -0
- data/ext/crlibm/missing +198 -0
- data/ext/crlibm/mkinstalldirs +40 -0
- data/ext/crlibm/rem_pio2_accurate.c +219 -0
- data/ext/crlibm/rem_pio2_accurate.h +53 -0
- data/ext/crlibm/scs_lib/AUTHORS +3 -0
- data/ext/crlibm/scs_lib/COPYING +504 -0
- data/ext/crlibm/scs_lib/ChangeLog +16 -0
- data/ext/crlibm/scs_lib/INSTALL +215 -0
- data/ext/crlibm/scs_lib/Makefile.am +18 -0
- data/ext/crlibm/scs_lib/Makefile.in +328 -0
- data/ext/crlibm/scs_lib/NEWS +0 -0
- data/ext/crlibm/scs_lib/README +9 -0
- data/ext/crlibm/scs_lib/TODO +4 -0
- data/ext/crlibm/scs_lib/addition_scs.c +623 -0
- data/ext/crlibm/scs_lib/config.guess +1461 -0
- data/ext/crlibm/scs_lib/config.sub +1566 -0
- data/ext/crlibm/scs_lib/configure +6226 -0
- data/ext/crlibm/scs_lib/division_scs.c +110 -0
- data/ext/crlibm/scs_lib/double2scs.c +174 -0
- data/ext/crlibm/scs_lib/install-sh +269 -0
- data/ext/crlibm/scs_lib/missing +198 -0
- data/ext/crlibm/scs_lib/mkinstalldirs +40 -0
- data/ext/crlibm/scs_lib/multiplication_scs.c +456 -0
- data/ext/crlibm/scs_lib/poly_fct.c +112 -0
- data/ext/crlibm/scs_lib/print_scs.c +73 -0
- data/ext/crlibm/scs_lib/rand_scs.c +63 -0
- data/ext/crlibm/scs_lib/scs.h +353 -0
- data/ext/crlibm/scs_lib/scs2double.c +391 -0
- data/ext/crlibm/scs_lib/scs2mpf.c +58 -0
- data/ext/crlibm/scs_lib/scs2mpfr.c +61 -0
- data/ext/crlibm/scs_lib/scs_private.c +23 -0
- data/ext/crlibm/scs_lib/scs_private.h +133 -0
- data/ext/crlibm/scs_lib/tests/tbx_timing.h +102 -0
- data/ext/crlibm/scs_lib/wrapper_scs.h +486 -0
- data/ext/crlibm/scs_lib/zero_scs.c +52 -0
- data/ext/crlibm/stamp-h.in +1 -0
- data/ext/crlibm/tests/Makefile.am +43 -0
- data/ext/crlibm/tests/Makefile.in +396 -0
- data/ext/crlibm/tests/blind_test.c +148 -0
- data/ext/crlibm/tests/generate_test_vectors.c +258 -0
- data/ext/crlibm/tests/soak_test.c +334 -0
- data/ext/crlibm/tests/test_common.c +627 -0
- data/ext/crlibm/tests/test_common.h +28 -0
- data/ext/crlibm/tests/test_perf.c +570 -0
- data/ext/crlibm/tests/test_val.c +249 -0
- data/ext/crlibm/trigo_accurate.c +500 -0
- data/ext/crlibm/trigo_accurate.h +331 -0
- data/ext/crlibm/trigo_fast.c +1219 -0
- data/ext/crlibm/trigo_fast.h +639 -0
- data/ext/crlibm/triple-double.h +878 -0
- data/ext/extconf.rb +31 -0
- data/ext/fpu.c +107 -0
- data/ext/jamis-mod.rb +591 -0
- data/lib/fpu.rb +287 -0
- data/lib/interval.rb +1170 -0
- data/lib/intervals.rb +212 -0
- data/lib/struct_float.rb +133 -0
- data/test/data_atan.txt +360 -0
- data/test/data_cos.txt +346 -0
- data/test/data_cosh.txt +3322 -0
- data/test/data_exp.txt +3322 -0
- data/test/data_log.txt +141 -0
- data/test/data_sin.txt +140 -0
- data/test/data_sinh.txt +3322 -0
- data/test/data_tan.txt +342 -0
- metadata +186 -0
@@ -0,0 +1,258 @@
|
|
1
|
+
/* This file is part of the crlibm library which is distributed under
|
2
|
+
the LGPL. This file itself is distributed under the GPL. Copyright
|
3
|
+
Florent de Dinechin and the Arenaire Team at ENS-Lyon
|
4
|
+
*/
|
5
|
+
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <stdlib.h>
|
8
|
+
#include "crlibm.h"
|
9
|
+
#include "crlibm_private.h"
|
10
|
+
#ifdef HAVE_MPFR_H /* stop here if MPFR not present */
|
11
|
+
#include "test_common.h"
|
12
|
+
#include <gmp.h>
|
13
|
+
#include <mpfr.h>
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
void usage(char *fct_name){
|
22
|
+
/* fprintf (stderr, "\n%s: Searches at random difficult-to-round cases for correctly rounded libraries \n", fct_name); */
|
23
|
+
fprintf (stderr, "\nUsage: %s function n seed \n", fct_name);
|
24
|
+
fprintf (stderr, " function : name of function to test \n");
|
25
|
+
fprintf (stderr, " n : integer, only print out numbers with at least \n");
|
26
|
+
fprintf (stderr, " n identical bits after the round bit (try 10)\n");
|
27
|
+
fprintf (stderr, " seed : integer seed for the random number generator \n");
|
28
|
+
exit (1);
|
29
|
+
}
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
int main (int argc, char *argv[])
|
34
|
+
{
|
35
|
+
char* function_name;
|
36
|
+
int n;
|
37
|
+
int seed;
|
38
|
+
double worstcase;
|
39
|
+
char* rounding_mode="RN" ; /* needed by init function, otherwise unused */
|
40
|
+
db_number input, res_mpfr;
|
41
|
+
mpfr_t mp_res, mp_res53, mp_res54, mp_res_ru, mp_res_rd, mp_inpt;
|
42
|
+
|
43
|
+
/* The random number generator*/
|
44
|
+
double (*randfun) () = NULL;
|
45
|
+
/* Another unused random number generator*/
|
46
|
+
double (*randfun_perf) () = NULL;
|
47
|
+
|
48
|
+
/* The function we test */
|
49
|
+
double (*testfun_crlibm)() = NULL;
|
50
|
+
/* The function we trust */
|
51
|
+
int (*testfun_mpfr) () = NULL;
|
52
|
+
double (*testfun_libm) () = NULL;
|
53
|
+
double (*testfun_libultim) () = NULL;
|
54
|
+
double (*testfun_libmcr) () = NULL;
|
55
|
+
|
56
|
+
if ((argc != 4)) usage(argv[0]);
|
57
|
+
else{
|
58
|
+
function_name = argv[1];
|
59
|
+
sscanf(argv[2],"%d", &n);
|
60
|
+
sscanf(argv[3],"%d", &seed);
|
61
|
+
|
62
|
+
test_init(/* pointers to returned value */
|
63
|
+
&randfun_perf, /* unused here*/
|
64
|
+
&randfun,
|
65
|
+
&testfun_crlibm,
|
66
|
+
&testfun_mpfr,
|
67
|
+
&testfun_libultim, /* unused here*/
|
68
|
+
&testfun_libmcr, /* unused here*/
|
69
|
+
&testfun_libm, /* unused here*/
|
70
|
+
&worstcase, /* unused here*/
|
71
|
+
/* arguments */
|
72
|
+
function_name,
|
73
|
+
rounding_mode /* unused here*/ ) ;
|
74
|
+
|
75
|
+
mpfr_init2(mp_res, 53+n+1);
|
76
|
+
mpfr_init2(mp_res_ru, 53);
|
77
|
+
mpfr_init2(mp_res_rd, 53);
|
78
|
+
mpfr_init2(mp_res53, 53);
|
79
|
+
mpfr_init2(mp_res54, 54);
|
80
|
+
mpfr_init2(mp_inpt, 53);
|
81
|
+
printf("# Bad cases generated by %s %s %s %s \n", argv[0], argv[1], argv[2], argv[3] );
|
82
|
+
|
83
|
+
srand(seed);
|
84
|
+
|
85
|
+
while(1+1==2){
|
86
|
+
input.d = randfun();
|
87
|
+
mpfr_set_d(mp_inpt, input.d, GMP_RNDN);
|
88
|
+
testfun_mpfr(mp_res, mp_inpt, GMP_RNDN);
|
89
|
+
testfun_mpfr(mp_res54, mp_inpt, GMP_RNDN);
|
90
|
+
if(mpfr_cmp (mp_res54, mp_res)==0) {
|
91
|
+
/* This is a difficult to round case. Now in which direction ? */
|
92
|
+
/* First filter results equal to zero, infty, 1.0 */
|
93
|
+
res_mpfr.d = mpfr_get_d(mp_res, GMP_RNDN);
|
94
|
+
if( ((res_mpfr.i[HI] & 0x7ff00000) != 0x7ff00000) && (res_mpfr.d!=0.0) && (res_mpfr.d!=1.0) ){
|
95
|
+
|
96
|
+
/* is it difficult to round to nearest ? */
|
97
|
+
testfun_mpfr(mp_res53, mp_inpt, GMP_RNDN);
|
98
|
+
if(mpfr_cmp (mp_res54, mp_res53)!=0) {
|
99
|
+
res_mpfr.d = mpfr_get_d(mp_res53, GMP_RNDN);
|
100
|
+
printf("N %08x %08x %08x %08x # %1.30e\n",
|
101
|
+
input.i[HI], input.i[LO],
|
102
|
+
res_mpfr.i[HI], res_mpfr.i[LO],
|
103
|
+
input.d);
|
104
|
+
}
|
105
|
+
else{
|
106
|
+
/* now we have mpfr_cmp (mp_res, mp_res53)==0
|
107
|
+
Test the three directed rounding modes */
|
108
|
+
testfun_mpfr(mp_res53, mp_inpt, GMP_RNDD);
|
109
|
+
res_mpfr.d = mpfr_get_d(mp_res53, GMP_RNDN);
|
110
|
+
printf("M %08x %08x %08x %08x # %1.30e\n",
|
111
|
+
input.i[HI], input.i[LO],
|
112
|
+
res_mpfr.i[HI], res_mpfr.i[LO],
|
113
|
+
input.d);
|
114
|
+
|
115
|
+
testfun_mpfr(mp_res53, mp_inpt, GMP_RNDU);
|
116
|
+
res_mpfr.d = mpfr_get_d(mp_res53, GMP_RNDN);
|
117
|
+
printf("P %08x %08x %08x %08x # %1.30e\n",
|
118
|
+
input.i[HI], input.i[LO],
|
119
|
+
res_mpfr.i[HI], res_mpfr.i[LO],
|
120
|
+
input.d);
|
121
|
+
|
122
|
+
testfun_mpfr(mp_res53, mp_inpt, GMP_RNDZ);
|
123
|
+
res_mpfr.d = mpfr_get_d(mp_res53, GMP_RNDN);
|
124
|
+
printf("Z %08x %08x %08x %08x # %1.30e\n",
|
125
|
+
input.i[HI], input.i[LO],
|
126
|
+
res_mpfr.i[HI], res_mpfr.i[LO],
|
127
|
+
input.d);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
return 0;
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
#if 0
|
141
|
+
int
|
142
|
+
main (int argc, char *argv[])
|
143
|
+
{
|
144
|
+
double left = atof(argv[1]); /* left side of the interval */
|
145
|
+
double right = atof(argv[2]); /* right side of the interval */
|
146
|
+
int n = atoi (argv[1]); /* how many bits do we want */
|
147
|
+
mpfr_t x, dx, pisur4, y, s, c, z, y2;
|
148
|
+
i nt i, found;
|
149
|
+
double j, k;
|
150
|
+
mpfr_init2 (x, 53);
|
151
|
+
mpfr_init2 (y, 53);
|
152
|
+
mpfr_init2 (y2, 53);
|
153
|
+
mpfr_init2 (z, 53);
|
154
|
+
mpfr_init2 (dx, 53);
|
155
|
+
mpfr_init2 (pisur4, 53);
|
156
|
+
mpfr_init2 (s, 53 + n - 1);
|
157
|
+
|
158
|
+
/* Pi/4 */
|
159
|
+
/* mpfr_const_pi (pisur4, GMP_RNDU); */
|
160
|
+
/* mpfr_div_ui (pisur4, pisur4, 4, GMP_RNDU); */
|
161
|
+
|
162
|
+
/* mpfr_set (dx, pisur4, GMP_RNDN); */
|
163
|
+
/* mpfr_div_ui (dx, dx, n, GMP_RNDN); /\* Pi/(4n) *\/ */
|
164
|
+
/* mpfr_div_ui (x, dx, 2, GMP_RNDN); /\* x0 = dx/2 *\/ */
|
165
|
+
|
166
|
+
while(1+1==2) {
|
167
|
+
}
|
168
|
+
i = 0;
|
169
|
+
while (mpfr_cmp_d (x, minx) < 0)
|
170
|
+
{
|
171
|
+
i ++;
|
172
|
+
mpfr_add (x, x, dx, GMP_RNDN);
|
173
|
+
}
|
174
|
+
while (mpfr_cmp (x, pisur4) <= 0)
|
175
|
+
{
|
176
|
+
i ++;
|
177
|
+
mpfr_set (y, x, GMP_RNDN);
|
178
|
+
mpfr_set (y2, x, GMP_RNDN);
|
179
|
+
found = 0;
|
180
|
+
j = k = 0.0;
|
181
|
+
while (!found)
|
182
|
+
{
|
183
|
+
mpfr_sin (s, y, GMP_RNDN);
|
184
|
+
mpfr_set (z, s, GMP_RNDN);
|
185
|
+
if (mpfr_cmp (z, s) == 0)
|
186
|
+
{
|
187
|
+
mpfr_cos (c, y, GMP_RNDN);
|
188
|
+
mpfr_set (z, c, GMP_RNDN);
|
189
|
+
found = mpfr_cmp (z, c) == 0;
|
190
|
+
if (found)
|
191
|
+
{
|
192
|
+
mpfr_t t;
|
193
|
+
mpfr_init2 (t, 200);
|
194
|
+
printf ("j=%1.0f ", j);
|
195
|
+
mpfr_sin (t, y, GMP_RNDN);
|
196
|
+
mpfr_sub (t, t, s, GMP_RNDN);
|
197
|
+
printf ("[%lu,", mpfr_get_exp (s) - mpfr_get_exp (t) - 53);
|
198
|
+
mpfr_cos (t, y, GMP_RNDN);
|
199
|
+
mpfr_sub (t, t, c, GMP_RNDN);
|
200
|
+
printf ("%lu] ", mpfr_get_exp (c) - mpfr_get_exp (t) - 53);
|
201
|
+
mpfr_clear (t);
|
202
|
+
mpfr_dump (y);
|
203
|
+
break;
|
204
|
+
}
|
205
|
+
}
|
206
|
+
j++;
|
207
|
+
mpfr_nextabove (y);
|
208
|
+
k --;
|
209
|
+
mpfr_nextbelow (y2);
|
210
|
+
mpfr_sin (s, y2, GMP_RNDN);
|
211
|
+
mpfr_set (z, s, GMP_RNDN);
|
212
|
+
if (mpfr_cmp (z, s) == 0)
|
213
|
+
{
|
214
|
+
mpfr_cos (c, y2, GMP_RNDN);
|
215
|
+
mpfr_set (z, c, GMP_RNDN);
|
216
|
+
found = mpfr_cmp (z, c) == 0;
|
217
|
+
if (found)
|
218
|
+
{
|
219
|
+
mpfr_t t;
|
220
|
+
mpfr_init2 (t, 200);
|
221
|
+
printf ("j=%1.0f ", k);
|
222
|
+
mpfr_sin (t, y2, GMP_RNDN);
|
223
|
+
mpfr_sub (t, t, s, GMP_RNDN);
|
224
|
+
printf ("[%lu,", mpfr_get_exp (s) - mpfr_get_exp (t) - 53);
|
225
|
+
mpfr_cos (t, y2, GMP_RNDN);
|
226
|
+
mpfr_sub (t, t, c, GMP_RNDN);
|
227
|
+
printf ("%lu] ", mpfr_get_exp (c) - mpfr_get_exp (t) - 53);
|
228
|
+
mpfr_clear (t);
|
229
|
+
mpfr_dump (y2);
|
230
|
+
break;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
mpfr_add (x, x, dx, GMP_RNDN);
|
235
|
+
}
|
236
|
+
mpfr_clear (x);
|
237
|
+
mpfr_clear (dx);
|
238
|
+
mpfr_clear (pisur4);
|
239
|
+
mpfr_clear (y);
|
240
|
+
mpfr_clear (y2);
|
241
|
+
mpfr_clear (s);
|
242
|
+
mpfr_clear (c);
|
243
|
+
mpfr_clear (z);
|
244
|
+
return 0;
|
245
|
+
}
|
246
|
+
|
247
|
+
#endif
|
248
|
+
|
249
|
+
#else
|
250
|
+
int main (int argc, char *argv[])
|
251
|
+
{
|
252
|
+
printf("Sorry, I need to be compiled against MPFR\n");
|
253
|
+
return 0;
|
254
|
+
}
|
255
|
+
#endif
|
256
|
+
|
257
|
+
|
258
|
+
|
@@ -0,0 +1,334 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <string.h>
|
4
|
+
#include <math.h>
|
5
|
+
#include "crlibm.h"
|
6
|
+
#include "crlibm_private.h"
|
7
|
+
#ifdef HAVE_MPFR_H /* stop here if MPFR not present */
|
8
|
+
#include "test_common.h"
|
9
|
+
#include <gmp.h>
|
10
|
+
#include <mpfr.h>
|
11
|
+
|
12
|
+
#ifdef HAVE_MATHLIB_H
|
13
|
+
#include <MathLib.h>
|
14
|
+
#endif
|
15
|
+
|
16
|
+
/* Stupidely soak-tests a function against mpfr */
|
17
|
+
|
18
|
+
/* if set to 1, print out the worst error (wiht values of x)
|
19
|
+
if set to 0, don't print out worst error information */
|
20
|
+
#define WORST_ERROR_REPORT 1
|
21
|
+
|
22
|
+
/* if set to 1, print out detailed errors (vith values of x)
|
23
|
+
if set to 0, only count the errors and print out the count */
|
24
|
+
#define DETAILED_REPORT 1
|
25
|
+
|
26
|
+
/* if set to 1, print out errors due to NaNs
|
27
|
+
if set to 0, don't print NaNs' errors */
|
28
|
+
#define PRINT_NAN 0
|
29
|
+
/* What we are looking for here is misrounding. Therefore these tests
|
30
|
+
concern only intervals on which the function does something
|
31
|
+
useful. For example for exp, it is enough to soaktest on -1024,1024.
|
32
|
+
|
33
|
+
To achieve this we have several random generator function, tailored
|
34
|
+
for each function or group of function.
|
35
|
+
|
36
|
+
The other cases (including all the special cases) are supposedly
|
37
|
+
tested exhaustively by the other programs of this directory. */
|
38
|
+
|
39
|
+
/* Basic-like programming with global variables: */
|
40
|
+
db_number input, input2, res_crlibm, res_mpfr, res_libultim, res_libmcr, res_libm;
|
41
|
+
mpfr_t mp_res, mp_inpt, mp_inpt2;
|
42
|
+
|
43
|
+
/* The random number generator*/
|
44
|
+
double (*randfun) () = NULL;
|
45
|
+
/* Another unused random number generator*/
|
46
|
+
double (*randfun_perf) () = NULL;
|
47
|
+
|
48
|
+
/* The function we test */
|
49
|
+
double (*testfun_crlibm)() = NULL;
|
50
|
+
/* The function we trust */
|
51
|
+
int (*testfun_mpfr) () = NULL;
|
52
|
+
/* The function to show off against for accuracy */
|
53
|
+
double (*testfun_libm) () = NULL;
|
54
|
+
/* The function to show off against for performance */
|
55
|
+
double (*testfun_libultim) () = NULL;
|
56
|
+
/* */
|
57
|
+
double (*testfun_libmcr) () = NULL;
|
58
|
+
|
59
|
+
|
60
|
+
/*
|
61
|
+
* Rounding mode to test
|
62
|
+
*/
|
63
|
+
mp_rnd_t mpfr_rnd_mode;
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
/* indicate the number of argument taken by the function */
|
68
|
+
int nbarg;
|
69
|
+
|
70
|
+
|
71
|
+
#define PRINT_INPUT_ERROR\
|
72
|
+
printf(" x =%.70e \n (%08x %08x) \n", input.d, input.i[HI], input.i[LO]);\
|
73
|
+
if (nbarg==2){\
|
74
|
+
printf(" y =%.70e \n (%08x %08x) \n",input2.d,input2.i[HI],input2.i[LO]);\
|
75
|
+
}\
|
76
|
+
|
77
|
+
|
78
|
+
/*
|
79
|
+
* Give the number of missrounded results
|
80
|
+
*/
|
81
|
+
|
82
|
+
void test_all() {
|
83
|
+
long long int
|
84
|
+
failures_libm=0,
|
85
|
+
#ifdef HAVE_MATHLIB_H
|
86
|
+
failures_libultim=0,
|
87
|
+
#endif
|
88
|
+
#ifdef HAVE_LIBMCR_H
|
89
|
+
failures_libmcr=0,
|
90
|
+
#endif
|
91
|
+
failures_crlibm=0;
|
92
|
+
long long int i;
|
93
|
+
double worst_err, global_worst_err=-200;
|
94
|
+
db_number global_worst_inpt, global_worst_inpt2;
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
i=0;
|
100
|
+
while(1+1==2){
|
101
|
+
input.d = randfun();
|
102
|
+
input2.d = randfun();
|
103
|
+
if (nbarg==1){
|
104
|
+
res_crlibm.d = testfun_crlibm(input.d);
|
105
|
+
res_libm.d = testfun_libm(input.d);
|
106
|
+
#ifdef HAVE_MATHLIB_H
|
107
|
+
if(mpfr_rnd_mode==GMP_RNDN && testfun_libultim != NULL) /* not all the functions are in libultim */
|
108
|
+
res_libultim.d = testfun_libultim(input.d);
|
109
|
+
#endif
|
110
|
+
#ifdef HAVE_LIBMCR_H
|
111
|
+
if(mpfr_rnd_mode==GMP_RNDN && testfun_libmcr != NULL) /* not all the functions are in libmcr */
|
112
|
+
res_libmcr.d = testfun_libmcr(input.d);
|
113
|
+
#endif
|
114
|
+
mpfr_set_d(mp_inpt, input.d, GMP_RNDN);
|
115
|
+
testfun_mpfr(mp_res, mp_inpt, mpfr_rnd_mode);
|
116
|
+
res_mpfr.d = mpfr_get_d(mp_res, mpfr_rnd_mode);
|
117
|
+
}
|
118
|
+
|
119
|
+
if (nbarg==2){
|
120
|
+
res_crlibm.d = testfun_crlibm(input.d, input2.d);
|
121
|
+
res_libm.d = testfun_libm(input.d, input2.d);
|
122
|
+
#ifdef HAVE_MATHLIB_H
|
123
|
+
if(mpfr_rnd_mode==GMP_RNDN && testfun_libultim != NULL) /* not all the functions are in libultim */
|
124
|
+
res_libultim.d = testfun_libultim(input.d, input2.d);
|
125
|
+
#endif
|
126
|
+
#ifdef HAVE_LIBMCR_H
|
127
|
+
if(mpfr_rnd_mode==GMP_RNDN && testfun_libmcr != NULL) /* not all the functions are in libmcr */
|
128
|
+
res_libmcr.d = testfun_libmcr(input.d, input2.d);
|
129
|
+
#endif
|
130
|
+
mpfr_set_d(mp_inpt, input.d, GMP_RNDN);
|
131
|
+
mpfr_set_d(mp_inpt2, input2.d, GMP_RNDN);
|
132
|
+
testfun_mpfr(mp_res, mp_inpt, mp_inpt2, mpfr_rnd_mode);
|
133
|
+
res_mpfr.d = mpfr_get_d(mp_res, mpfr_rnd_mode);
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
#if PRINT_NAN
|
138
|
+
if(1){
|
139
|
+
#else
|
140
|
+
if((res_mpfr.i[HI] & 0x7ff00000) != 0x7ff00000){
|
141
|
+
#endif
|
142
|
+
if( (res_crlibm.i[LO] != res_mpfr.i[LO])
|
143
|
+
|| (res_crlibm.i[HI] != res_mpfr.i[HI]) ){
|
144
|
+
#if DETAILED_REPORT
|
145
|
+
printf("*** CRLIBM ERROR ***\n");
|
146
|
+
PRINT_INPUT_ERROR;
|
147
|
+
printf("crlibm gives %.50e \n (%08x %08x) \n",
|
148
|
+
res_crlibm.d,
|
149
|
+
res_crlibm.i[HI],
|
150
|
+
res_crlibm.i[LO]);
|
151
|
+
printf("MPFR gives %.50e \n (%08x %08x) \n\n",
|
152
|
+
res_mpfr.d,
|
153
|
+
res_mpfr.i[HI],
|
154
|
+
res_mpfr.i[LO]);
|
155
|
+
#endif
|
156
|
+
#if WORST_ERROR_REPORT
|
157
|
+
mpfr_set_d(mp_inpt, res_crlibm.d, GMP_RNDN);
|
158
|
+
mpfr_sub(mp_inpt, mp_inpt, mp_res, GMP_RNDN);
|
159
|
+
mpfr_div(mp_inpt, mp_inpt, mp_res, GMP_RNDN);
|
160
|
+
mpfr_abs(mp_inpt, mp_inpt, GMP_RNDN);
|
161
|
+
mpfr_log2(mp_inpt, mp_inpt, GMP_RNDN);
|
162
|
+
worst_err=mpfr_get_d(mp_inpt, GMP_RNDN);
|
163
|
+
|
164
|
+
if (worst_err>global_worst_err){
|
165
|
+
global_worst_err=worst_err;
|
166
|
+
global_worst_inpt.d = input.d;
|
167
|
+
global_worst_inpt2.d = input2.d;
|
168
|
+
}
|
169
|
+
printf("Worst crlibm relative error so far : 2^(%f)\n",global_worst_err);
|
170
|
+
printf(" for x =%.50e (%08x %08x) \n",
|
171
|
+
global_worst_inpt.d,
|
172
|
+
global_worst_inpt.i[HI],
|
173
|
+
global_worst_inpt.i[LO]);
|
174
|
+
if (nbarg==2){
|
175
|
+
printf(" y =%.50e (%08x %08x) \n",
|
176
|
+
global_worst_inpt2.d,
|
177
|
+
global_worst_inpt2.i[HI],
|
178
|
+
global_worst_inpt2.i[LO]);
|
179
|
+
}
|
180
|
+
#endif
|
181
|
+
|
182
|
+
failures_crlibm++;
|
183
|
+
}
|
184
|
+
|
185
|
+
if( (res_libm.i[LO] != res_mpfr.i[LO])
|
186
|
+
|| (res_libm.i[HI] != res_mpfr.i[HI]) ) failures_libm++;
|
187
|
+
|
188
|
+
#ifdef HAVE_MATHLIB_H
|
189
|
+
if(mpfr_rnd_mode==0 && testfun_libultim != NULL
|
190
|
+
&& ((res_libultim.i[LO] != res_mpfr.i[LO])
|
191
|
+
|| (res_libultim.i[HI] != res_mpfr.i[HI]) )){
|
192
|
+
#if DETAILED_REPORT
|
193
|
+
printf("*** IBM ULTIM ERROR ***\n");
|
194
|
+
PRINT_INPUT_ERROR;
|
195
|
+
printf("libultim gives %.50e \n (%08x %08x) \n",
|
196
|
+
res_libultim.d,
|
197
|
+
res_libultim.i[HI],
|
198
|
+
res_libultim.i[LO]);
|
199
|
+
printf("MPFR gives %.50e \n (%08x %08x) \n\n",
|
200
|
+
res_mpfr.d,
|
201
|
+
res_mpfr.i[HI],
|
202
|
+
res_mpfr.i[LO]);
|
203
|
+
#endif
|
204
|
+
failures_libultim++;
|
205
|
+
}
|
206
|
+
#endif
|
207
|
+
#ifdef HAVE_LIBMCR_H
|
208
|
+
if(mpfr_rnd_mode==0 && testfun_libmcr != NULL
|
209
|
+
&& ((res_libmcr.i[LO] != res_mpfr.i[LO])
|
210
|
+
|| (res_libmcr.i[HI] != res_mpfr.i[HI]) )){
|
211
|
+
#if DETAILED_REPORT
|
212
|
+
printf("*** LIBMCR ERROR ***\n");
|
213
|
+
PRINT_INPUT_ERROR;
|
214
|
+
printf("libmcr gives %.50e \n (%08x %08x) \n",
|
215
|
+
res_libmcr.d,
|
216
|
+
res_libmcr.i[HI],
|
217
|
+
res_libmcr.i[LO]);
|
218
|
+
printf("MPFR gives %.50e \n (%08x %08x) \n\n",
|
219
|
+
res_mpfr.d,
|
220
|
+
res_mpfr.i[HI],
|
221
|
+
res_mpfr.i[LO]);
|
222
|
+
#endif
|
223
|
+
failures_libmcr++;
|
224
|
+
}
|
225
|
+
#endif
|
226
|
+
}
|
227
|
+
i++;
|
228
|
+
if((i % 10000)==0) {
|
229
|
+
printf(" CRLIBM : %lld failures out of %lld (ratio %e) \n",failures_crlibm, i,
|
230
|
+
((double)failures_crlibm)/(double)i);
|
231
|
+
printf(" LIBM : %lld failures out of %lld (ratio %e) \n",failures_libm, i,
|
232
|
+
((double)failures_libm)/(double)i);
|
233
|
+
#ifdef HAVE_MATHLIB_H
|
234
|
+
printf(" IBM LIBULTIM : %lld failures out of %lld (ratio %e) \n",failures_libultim, i,
|
235
|
+
((double)failures_libultim)/(double)i);
|
236
|
+
#endif
|
237
|
+
#ifdef HAVE_LIBMCR_H
|
238
|
+
printf(" SUN LIBMCR : %lld failures out of %lld (ratio %e) \n",failures_libmcr, i,
|
239
|
+
((double)failures_libmcr)/(double)i);
|
240
|
+
#endif
|
241
|
+
printf("\n");
|
242
|
+
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
|
248
|
+
void test_random_gen() {
|
249
|
+
|
250
|
+
double x, min, max;
|
251
|
+
min=0;max=0;
|
252
|
+
|
253
|
+
while(1+1==2) {
|
254
|
+
x = randfun();
|
255
|
+
if(x<min) min=x;
|
256
|
+
if(x>max) max=x;
|
257
|
+
printf("x=%f (%f %f)\n",
|
258
|
+
x, min, max
|
259
|
+
);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
|
265
|
+
void usage(char *fct_name){
|
266
|
+
/* fprintf (stderr, "\n%s: Soak-test for crlibm and other mathematical libraries \n", fct_name); */
|
267
|
+
fprintf (stderr, "\nUsage: %s function (RN|RU|RD|RZ) seed \n", fct_name);
|
268
|
+
fprintf (stderr, " function : name of function to test \n");
|
269
|
+
fprintf (stderr, " (RN|RU|RD|RZ) : rounding mode, \n");
|
270
|
+
fprintf (stderr, " seed : integer seed for the random number generator \n");
|
271
|
+
exit (1);
|
272
|
+
}
|
273
|
+
|
274
|
+
|
275
|
+
|
276
|
+
int main (int argc, char *argv[])
|
277
|
+
{
|
278
|
+
char* rounding_mode;
|
279
|
+
char* function_name;
|
280
|
+
int seed;
|
281
|
+
double worstcase;
|
282
|
+
|
283
|
+
if ((argc != 4)) usage(argv[0]);
|
284
|
+
else{
|
285
|
+
function_name = argv[1];
|
286
|
+
rounding_mode = argv[2];
|
287
|
+
sscanf(argv[3],"%d", &seed);
|
288
|
+
|
289
|
+
if (strcmp(function_name,"pow")==0) nbarg=2;
|
290
|
+
else nbarg=1;
|
291
|
+
|
292
|
+
crlibm_init();
|
293
|
+
|
294
|
+
test_init(/* pointers to returned value */
|
295
|
+
&randfun_perf, /* unused here*/
|
296
|
+
&randfun,
|
297
|
+
&testfun_crlibm,
|
298
|
+
&testfun_mpfr,
|
299
|
+
&testfun_libultim,
|
300
|
+
&testfun_libmcr,
|
301
|
+
&testfun_libm,
|
302
|
+
&worstcase,
|
303
|
+
/* arguments */
|
304
|
+
function_name,
|
305
|
+
rounding_mode ) ;
|
306
|
+
|
307
|
+
mpfr_init2(mp_res, 153);
|
308
|
+
mpfr_init2(mp_inpt, 53);
|
309
|
+
mpfr_init2(mp_inpt2, 53);
|
310
|
+
if (strcmp(rounding_mode,"RU")==0) mpfr_rnd_mode = GMP_RNDU;
|
311
|
+
else if (strcmp(rounding_mode,"RD")==0) mpfr_rnd_mode = GMP_RNDD;
|
312
|
+
else if (strcmp(rounding_mode,"RZ")==0) mpfr_rnd_mode = GMP_RNDZ;
|
313
|
+
else {
|
314
|
+
mpfr_rnd_mode = GMP_RNDN;
|
315
|
+
rounding_mode="RN" ;
|
316
|
+
}
|
317
|
+
|
318
|
+
printf("Testing %s function with rounding mode : %s \n", function_name, rounding_mode);
|
319
|
+
|
320
|
+
srand(seed);
|
321
|
+
|
322
|
+
test_all();
|
323
|
+
}
|
324
|
+
return 0;
|
325
|
+
}
|
326
|
+
|
327
|
+
|
328
|
+
#else
|
329
|
+
int main (int argc, char *argv[])
|
330
|
+
{
|
331
|
+
printf("Sorry, I need to be compiled against MPFR\n (get it from www.mpfr.org, then: configure --enable-mpfr)\n");
|
332
|
+
return 0;
|
333
|
+
}
|
334
|
+
#endif
|