tgeneric.c revision 1.1.1.3 1 1.1 mrg /* Generic test file for functions with one or two arguments (the second being
2 1.1.1.3 mrg either mpfr_t or double or unsigned long).
3 1.1 mrg
4 1.1.1.3 mrg Copyright 2001-2016 Free Software Foundation, Inc.
5 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA.
6 1.1 mrg
7 1.1 mrg This file is part of the GNU MPFR Library.
8 1.1 mrg
9 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
10 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
11 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
12 1.1 mrg option) any later version.
13 1.1 mrg
14 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
15 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 1.1 mrg License for more details.
18 1.1 mrg
19 1.1 mrg You should have received a copy of the GNU Lesser General Public License
20 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 1.1 mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23 1.1 mrg
24 1.1.1.3 mrg /* Define TWO_ARGS for two-argument functions like mpfr_pow.
25 1.1.1.3 mrg Define DOUBLE_ARG1 or DOUBLE_ARG2 for function with a double operand in
26 1.1.1.3 mrg first or second place like sub_d or d_sub.
27 1.1.1.3 mrg Define ULONG_ARG1 or ULONG_ARG2 for function with an unsigned long
28 1.1.1.3 mrg operand in first or second place like sub_ui or ui_sub. */
29 1.1.1.3 mrg
30 1.1.1.3 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) || \
31 1.1.1.3 mrg defined(ULONG_ARG1) || defined(ULONG_ARG2)
32 1.1.1.3 mrg #define TWO_ARGS_ALL
33 1.1.1.3 mrg #endif
34 1.1 mrg
35 1.1 mrg #ifndef TEST_RANDOM_POS
36 1.1 mrg /* For the random function: one number on two is negative. */
37 1.1 mrg #define TEST_RANDOM_POS 256
38 1.1 mrg #endif
39 1.1 mrg
40 1.1 mrg #ifndef TEST_RANDOM_POS2
41 1.1 mrg /* For the random function: one number on two is negative. */
42 1.1 mrg #define TEST_RANDOM_POS2 256
43 1.1 mrg #endif
44 1.1 mrg
45 1.1 mrg #ifndef TEST_RANDOM_EMIN
46 1.1 mrg #define TEST_RANDOM_EMIN -256
47 1.1 mrg #endif
48 1.1 mrg
49 1.1 mrg #ifndef TEST_RANDOM_EMAX
50 1.1 mrg #define TEST_RANDOM_EMAX 255
51 1.1 mrg #endif
52 1.1 mrg
53 1.1.1.3 mrg #ifndef TEST_RANDOM_ALWAYS_SCALE
54 1.1.1.3 mrg #define TEST_RANDOM_ALWAYS_SCALE 0
55 1.1.1.3 mrg #endif
56 1.1.1.3 mrg
57 1.1.1.2 mrg /* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug,
58 1.1.1.2 mrg then define TGENERIC_SO_TEST with an adequate test (possibly 0) to
59 1.1.1.2 mrg omit this particular case. */
60 1.1.1.2 mrg #ifndef TGENERIC_SO_TEST
61 1.1.1.2 mrg #define TGENERIC_SO_TEST 1
62 1.1.1.2 mrg #endif
63 1.1.1.2 mrg
64 1.1.1.2 mrg #define STR(F) #F
65 1.1.1.2 mrg #define MAKE_STR(S) STR(S)
66 1.1.1.2 mrg
67 1.1 mrg /* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions
68 1.1 mrg * with 2 arguments. See <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>.
69 1.1 mrg */
70 1.1 mrg #define TGENERIC_FAIL(S, X, U) \
71 1.1 mrg do \
72 1.1 mrg { \
73 1.1.1.3 mrg printf ("tgeneric: %s\nx = ", (S)); \
74 1.1.1.3 mrg mpfr_dump (X);; \
75 1.1.1.3 mrg if ((void *) (U) != 0) \
76 1.1 mrg { \
77 1.1 mrg printf ("u = "); \
78 1.1.1.3 mrg mpfr_dump (U); \
79 1.1 mrg } \
80 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s, inexact = %d\nflags =", \
81 1.1.1.3 mrg (unsigned int) yprec, mpfr_print_rnd_mode (rnd), \
82 1.1.1.3 mrg compare); \
83 1.1.1.3 mrg flags_out (flags); \
84 1.1 mrg exit (1); \
85 1.1 mrg } \
86 1.1 mrg while (0)
87 1.1 mrg
88 1.1.1.3 mrg #define TGENERIC_CHECK_AUX(S, EXPR, U) \
89 1.1.1.3 mrg do \
90 1.1.1.3 mrg if (!(EXPR)) \
91 1.1.1.3 mrg TGENERIC_FAIL (S " for " MAKE_STR(TEST_FUNCTION), x, U); \
92 1.1.1.2 mrg while (0)
93 1.1.1.2 mrg
94 1.1 mrg #undef TGENERIC_CHECK
95 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
96 1.1.1.2 mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u)
97 1.1 mrg #else
98 1.1.1.2 mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0)
99 1.1 mrg #endif
100 1.1 mrg
101 1.1 mrg #ifdef DEBUG_TGENERIC
102 1.1 mrg #define TGENERIC_IAUX(F,P,X,U) \
103 1.1 mrg do \
104 1.1 mrg { \
105 1.1 mrg printf ("tgeneric: testing function " STR(F) \
106 1.1 mrg ", %s, target prec = %lu\nx = ", \
107 1.1 mrg mpfr_print_rnd_mode (rnd), (unsigned long) (P)); \
108 1.1.1.3 mrg mpfr_dump (X); \
109 1.1.1.3 mrg if ((void *) (U) != 0) \
110 1.1 mrg { \
111 1.1 mrg printf ("u = "); \
112 1.1.1.3 mrg mpfr_dump (U); \
113 1.1 mrg } \
114 1.1 mrg } \
115 1.1 mrg while (0)
116 1.1 mrg #undef TGENERIC_INFO
117 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
118 1.1 mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u)
119 1.1 mrg #else
120 1.1 mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0)
121 1.1 mrg #endif
122 1.1.1.3 mrg #endif /* DEBUG_TGENERIC */
123 1.1 mrg
124 1.1 mrg /* For some functions (for example cos), the argument reduction is too
125 1.1 mrg expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX
126 1.1 mrg to some reasonable value before including tgeneric.c. */
127 1.1 mrg #ifndef REDUCE_EMAX
128 1.1 mrg #define REDUCE_EMAX mpfr_get_emax ()
129 1.1 mrg #endif
130 1.1 mrg
131 1.1 mrg static void
132 1.1.1.2 mrg test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
133 1.1 mrg {
134 1.1 mrg mpfr_prec_t prec, xprec, yprec;
135 1.1 mrg mpfr_t x, y, z, t, w;
136 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
137 1.1 mrg mpfr_t u;
138 1.1.1.3 mrg #endif
139 1.1.1.3 mrg #if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
140 1.1 mrg double d;
141 1.1 mrg #endif
142 1.1.1.3 mrg #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
143 1.1.1.3 mrg unsigned long i;
144 1.1.1.3 mrg #endif
145 1.1 mrg mpfr_rnd_t rnd;
146 1.1 mrg int inexact, compare, compare2;
147 1.1 mrg unsigned int n;
148 1.1 mrg unsigned long ctrt = 0, ctrn = 0;
149 1.1.1.3 mrg int test_of = 1, test_uf = 1;
150 1.1 mrg mpfr_exp_t old_emin, old_emax;
151 1.1 mrg
152 1.1 mrg old_emin = mpfr_get_emin ();
153 1.1 mrg old_emax = mpfr_get_emax ();
154 1.1 mrg
155 1.1 mrg mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
156 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
157 1.1 mrg mpfr_init2 (u, MPFR_PREC_MIN);
158 1.1 mrg #endif
159 1.1 mrg
160 1.1 mrg /* generic test */
161 1.1 mrg for (prec = p0; prec <= p1; prec++)
162 1.1 mrg {
163 1.1 mrg mpfr_set_prec (z, prec);
164 1.1 mrg mpfr_set_prec (t, prec);
165 1.1 mrg yprec = prec + 10;
166 1.1 mrg mpfr_set_prec (y, yprec);
167 1.1 mrg mpfr_set_prec (w, yprec);
168 1.1 mrg
169 1.1 mrg /* Note: in precision p1, we test 4 special cases. */
170 1.1.1.2 mrg for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
171 1.1 mrg {
172 1.1.1.2 mrg int infinite_input = 0;
173 1.1.1.3 mrg unsigned int flags;
174 1.1.1.3 mrg mpfr_exp_t oemin, oemax;
175 1.1.1.2 mrg
176 1.1 mrg xprec = prec;
177 1.1 mrg if (randlimb () & 1)
178 1.1 mrg {
179 1.1.1.3 mrg /* In half cases, modify the precision of the inputs:
180 1.1.1.3 mrg If the base precision (for the result) is small,
181 1.1.1.3 mrg take a larger input precision in general, else
182 1.1.1.3 mrg take a smaller precision. */
183 1.1.1.3 mrg xprec *= (prec < 16 ? 256.0 : 1.0) *
184 1.1.1.3 mrg (double) randlimb () / MP_LIMB_T_MAX;
185 1.1 mrg if (xprec < MPFR_PREC_MIN)
186 1.1 mrg xprec = MPFR_PREC_MIN;
187 1.1 mrg }
188 1.1 mrg mpfr_set_prec (x, xprec);
189 1.1.1.3 mrg #if defined(TWO_ARGS)
190 1.1 mrg mpfr_set_prec (u, xprec);
191 1.1 mrg #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
192 1.1 mrg mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
193 1.1.1.3 mrg #elif defined(ULONG_ARG1) || defined(ULONG_ARG2)
194 1.1.1.3 mrg mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT);
195 1.1 mrg #endif
196 1.1 mrg
197 1.1 mrg if (n > 3 || prec < p1)
198 1.1 mrg {
199 1.1 mrg #if defined(RAND_FUNCTION)
200 1.1 mrg RAND_FUNCTION (x);
201 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
202 1.1 mrg RAND_FUNCTION (u);
203 1.1 mrg #endif
204 1.1.1.3 mrg #else /* ! defined(RAND_FUNCTION) */
205 1.1 mrg tests_default_random (x, TEST_RANDOM_POS,
206 1.1.1.3 mrg TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
207 1.1.1.3 mrg TEST_RANDOM_ALWAYS_SCALE);
208 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
209 1.1 mrg tests_default_random (u, TEST_RANDOM_POS2,
210 1.1.1.3 mrg TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
211 1.1.1.3 mrg TEST_RANDOM_ALWAYS_SCALE);
212 1.1 mrg #endif
213 1.1.1.3 mrg #endif /* ! defined(RAND_FUNCTION) */
214 1.1 mrg }
215 1.1 mrg else
216 1.1 mrg {
217 1.1 mrg /* Special cases tested in precision p1 if n <= 3. They are
218 1.1 mrg useful really in the extended exponent range. */
219 1.1.1.2 mrg #if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
220 1.1.1.2 mrg goto next_n;
221 1.1.1.2 mrg #endif
222 1.1 mrg set_emin (MPFR_EMIN_MIN);
223 1.1 mrg set_emax (MPFR_EMAX_MAX);
224 1.1 mrg if (n <= 1)
225 1.1 mrg {
226 1.1 mrg mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
227 1.1 mrg mpfr_set_exp (x, mpfr_get_emin ());
228 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
229 1.1 mrg mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
230 1.1 mrg mpfr_set_exp (u, mpfr_get_emin ());
231 1.1 mrg #endif
232 1.1 mrg }
233 1.1 mrg else /* 2 <= n <= 3 */
234 1.1 mrg {
235 1.1 mrg if (getenv ("MPFR_CHECK_MAX") == NULL)
236 1.1 mrg goto next_n;
237 1.1 mrg mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
238 1.1 mrg mpfr_setmax (x, REDUCE_EMAX);
239 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
240 1.1 mrg mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
241 1.1 mrg mpfr_setmax (u, mpfr_get_emax ());
242 1.1 mrg #endif
243 1.1 mrg }
244 1.1 mrg }
245 1.1 mrg
246 1.1.1.3 mrg #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
247 1.1.1.3 mrg i = randlimb ();
248 1.1.1.3 mrg inexact = mpfr_set_ui (u, i, MPFR_RNDN);
249 1.1.1.3 mrg MPFR_ASSERTN (inexact == 0);
250 1.1.1.3 mrg #endif
251 1.1.1.3 mrg
252 1.1.1.3 mrg /* Exponent range for the test. */
253 1.1.1.3 mrg oemin = mpfr_get_emin ();
254 1.1.1.3 mrg oemax = mpfr_get_emax ();
255 1.1.1.3 mrg
256 1.1 mrg rnd = RND_RAND ();
257 1.1 mrg mpfr_clear_flags ();
258 1.1 mrg #ifdef DEBUG_TGENERIC
259 1.1 mrg TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
260 1.1 mrg #endif
261 1.1 mrg #if defined(TWO_ARGS)
262 1.1 mrg compare = TEST_FUNCTION (y, x, u, rnd);
263 1.1 mrg #elif defined(DOUBLE_ARG1)
264 1.1 mrg d = mpfr_get_d (u, rnd);
265 1.1 mrg compare = TEST_FUNCTION (y, d, x, rnd);
266 1.1.1.2 mrg /* d can be infinite due to overflow in mpfr_get_d */
267 1.1.1.2 mrg infinite_input |= DOUBLE_ISINF (d);
268 1.1 mrg #elif defined(DOUBLE_ARG2)
269 1.1 mrg d = mpfr_get_d (u, rnd);
270 1.1 mrg compare = TEST_FUNCTION (y, x, d, rnd);
271 1.1.1.2 mrg /* d can be infinite due to overflow in mpfr_get_d */
272 1.1.1.2 mrg infinite_input |= DOUBLE_ISINF (d);
273 1.1.1.3 mrg #elif defined(ULONG_ARG1)
274 1.1.1.3 mrg compare = TEST_FUNCTION (y, i, x, rnd);
275 1.1.1.3 mrg #elif defined(ULONG_ARG2)
276 1.1.1.3 mrg compare = TEST_FUNCTION (y, x, i, rnd);
277 1.1 mrg #else
278 1.1 mrg compare = TEST_FUNCTION (y, x, rnd);
279 1.1 mrg #endif
280 1.1.1.3 mrg flags = __gmpfr_flags;
281 1.1.1.3 mrg if (mpfr_get_emin () != oemin ||
282 1.1.1.3 mrg mpfr_get_emax () != oemax)
283 1.1.1.3 mrg {
284 1.1.1.3 mrg printf ("tgeneric: the exponent range has been modified"
285 1.1.1.3 mrg " by the tested function!\n");
286 1.1.1.3 mrg exit (1);
287 1.1.1.3 mrg }
288 1.1.1.3 mrg TGENERIC_CHECK ("bad inexact flag",
289 1.1 mrg (compare != 0) ^ (mpfr_inexflag_p () == 0));
290 1.1 mrg ctrt++;
291 1.1 mrg
292 1.1.1.3 mrg /* Tests in a reduced exponent range. */
293 1.1.1.3 mrg {
294 1.1.1.3 mrg unsigned int oldflags = flags;
295 1.1.1.3 mrg mpfr_exp_t e, emin, emax;
296 1.1.1.3 mrg
297 1.1.1.3 mrg /* Determine the smallest exponent range containing the
298 1.1.1.3 mrg exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
299 1.1.1.3 mrg and output (y). */
300 1.1.1.3 mrg emin = MPFR_EMAX_MAX;
301 1.1.1.3 mrg emax = MPFR_EMIN_MIN;
302 1.1.1.3 mrg if (MPFR_IS_PURE_FP (x))
303 1.1.1.3 mrg {
304 1.1.1.3 mrg e = MPFR_GET_EXP (x);
305 1.1.1.3 mrg if (e < emin)
306 1.1.1.3 mrg emin = e;
307 1.1.1.3 mrg if (e > emax)
308 1.1.1.3 mrg emax = e;
309 1.1.1.3 mrg }
310 1.1 mrg #if defined(TWO_ARGS)
311 1.1.1.3 mrg if (MPFR_IS_PURE_FP (u))
312 1.1.1.3 mrg {
313 1.1.1.3 mrg e = MPFR_GET_EXP (u);
314 1.1.1.3 mrg if (e < emin)
315 1.1.1.3 mrg emin = e;
316 1.1.1.3 mrg if (e > emax)
317 1.1.1.3 mrg emax = e;
318 1.1.1.3 mrg }
319 1.1.1.3 mrg #endif
320 1.1.1.3 mrg if (MPFR_IS_PURE_FP (y))
321 1.1.1.3 mrg {
322 1.1.1.3 mrg e = MPFR_GET_EXP (y);
323 1.1.1.3 mrg if (test_of && e - 1 >= emax)
324 1.1.1.3 mrg {
325 1.1.1.3 mrg unsigned int ex_flags;
326 1.1.1.3 mrg
327 1.1.1.3 mrg mpfr_set_emax (e - 1);
328 1.1.1.3 mrg mpfr_clear_flags ();
329 1.1.1.3 mrg #if defined(TWO_ARGS)
330 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, u, rnd);
331 1.1.1.3 mrg #elif defined(DOUBLE_ARG1)
332 1.1.1.3 mrg inexact = TEST_FUNCTION (w, d, x, rnd);
333 1.1.1.3 mrg #elif defined(DOUBLE_ARG2)
334 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, d, rnd);
335 1.1.1.3 mrg #elif defined(ULONG_ARG1)
336 1.1.1.3 mrg inexact = TEST_FUNCTION (w, i, x, rnd);
337 1.1.1.3 mrg #elif defined(ULONG_ARG2)
338 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, i, rnd);
339 1.1.1.3 mrg #else
340 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, rnd);
341 1.1.1.3 mrg #endif
342 1.1.1.3 mrg flags = __gmpfr_flags;
343 1.1.1.3 mrg mpfr_set_emax (oemax);
344 1.1.1.3 mrg ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
345 1.1.1.3 mrg if (flags != ex_flags)
346 1.1.1.3 mrg {
347 1.1.1.3 mrg printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
348 1.1.1.3 mrg ", reduced exponent range [%"
349 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
350 1.1.1.3 mrg "d] (overflow test) on:\n",
351 1.1.1.3 mrg (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
352 1.1.1.3 mrg printf ("x = ");
353 1.1.1.3 mrg mpfr_dump (x);
354 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
355 1.1.1.3 mrg printf ("u = ");
356 1.1.1.3 mrg mpfr_dump (u);
357 1.1.1.3 mrg #endif
358 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s\n",
359 1.1.1.3 mrg (unsigned int) yprec,
360 1.1.1.3 mrg mpfr_print_rnd_mode (rnd));
361 1.1.1.3 mrg printf ("Expected flags =");
362 1.1.1.3 mrg flags_out (ex_flags);
363 1.1.1.3 mrg printf (" got flags =");
364 1.1.1.3 mrg flags_out (flags);
365 1.1.1.3 mrg printf ("inex = %d, w = ", inexact);
366 1.1.1.3 mrg mpfr_dump (w);
367 1.1.1.3 mrg exit (1);
368 1.1.1.3 mrg }
369 1.1.1.3 mrg test_of = 0; /* Overflow is tested only once. */
370 1.1.1.3 mrg }
371 1.1.1.3 mrg if (test_uf && e + 1 <= emin)
372 1.1.1.3 mrg {
373 1.1.1.3 mrg unsigned int ex_flags;
374 1.1.1.3 mrg
375 1.1.1.3 mrg mpfr_set_emin (e + 1);
376 1.1.1.3 mrg mpfr_clear_flags ();
377 1.1.1.3 mrg #if defined(TWO_ARGS)
378 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, u, rnd);
379 1.1.1.3 mrg #elif defined(DOUBLE_ARG1)
380 1.1.1.3 mrg inexact = TEST_FUNCTION (w, d, x, rnd);
381 1.1.1.3 mrg #elif defined(DOUBLE_ARG2)
382 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, d, rnd);
383 1.1.1.3 mrg #elif defined(ULONG_ARG1)
384 1.1.1.3 mrg inexact = TEST_FUNCTION (w, i, x, rnd);
385 1.1.1.3 mrg #elif defined(ULONG_ARG2)
386 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, i, rnd);
387 1.1.1.3 mrg #else
388 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, rnd);
389 1.1 mrg #endif
390 1.1.1.3 mrg flags = __gmpfr_flags;
391 1.1.1.3 mrg mpfr_set_emin (oemin);
392 1.1.1.3 mrg ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
393 1.1.1.3 mrg if (flags != ex_flags)
394 1.1.1.3 mrg {
395 1.1.1.3 mrg printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
396 1.1.1.3 mrg ", reduced exponent range [%"
397 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
398 1.1.1.3 mrg "d] (underflow test) on:\n",
399 1.1.1.3 mrg (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
400 1.1.1.3 mrg printf ("x = ");
401 1.1.1.3 mrg mpfr_dump (x);
402 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
403 1.1.1.3 mrg printf ("u = ");
404 1.1.1.3 mrg mpfr_dump (u);
405 1.1.1.3 mrg #endif
406 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s\n",
407 1.1.1.3 mrg (unsigned int) yprec,
408 1.1.1.3 mrg mpfr_print_rnd_mode (rnd));
409 1.1.1.3 mrg printf ("Expected flags =");
410 1.1.1.3 mrg flags_out (ex_flags);
411 1.1.1.3 mrg printf (" got flags =");
412 1.1.1.3 mrg flags_out (flags);
413 1.1.1.3 mrg printf ("inex = %d, w = ", inexact);
414 1.1.1.3 mrg mpfr_dump (w);
415 1.1.1.3 mrg exit (1);
416 1.1.1.3 mrg }
417 1.1.1.3 mrg test_uf = 0; /* Underflow is tested only once. */
418 1.1.1.3 mrg }
419 1.1.1.3 mrg if (e < emin)
420 1.1.1.3 mrg emin = e;
421 1.1.1.3 mrg if (e > emax)
422 1.1.1.3 mrg emax = e;
423 1.1.1.3 mrg }
424 1.1.1.3 mrg if (emin > emax)
425 1.1.1.3 mrg emin = emax; /* case where all values are singular */
426 1.1.1.3 mrg /* Consistency test in a reduced exponent range. Doing it
427 1.1.1.3 mrg for the first 10 samples and for prec == p1 (which has
428 1.1.1.3 mrg some special cases) should be sufficient. */
429 1.1.1.3 mrg if (ctrt <= 10 || prec == p1)
430 1.1.1.3 mrg {
431 1.1.1.3 mrg mpfr_set_emin (emin);
432 1.1.1.3 mrg mpfr_set_emax (emax);
433 1.1.1.2 mrg #ifdef DEBUG_TGENERIC
434 1.1.1.3 mrg /* Useful information in case of assertion failure. */
435 1.1.1.3 mrg printf ("tgeneric: reduced exponent range [%"
436 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
437 1.1.1.3 mrg (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
438 1.1.1.2 mrg #endif
439 1.1.1.3 mrg mpfr_clear_flags ();
440 1.1 mrg #if defined(TWO_ARGS)
441 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, u, rnd);
442 1.1 mrg #elif defined(DOUBLE_ARG1)
443 1.1.1.3 mrg inexact = TEST_FUNCTION (w, d, x, rnd);
444 1.1 mrg #elif defined(DOUBLE_ARG2)
445 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, d, rnd);
446 1.1.1.3 mrg #elif defined(ULONG_ARG1)
447 1.1.1.3 mrg inexact = TEST_FUNCTION (w, i, x, rnd);
448 1.1.1.3 mrg #elif defined(ULONG_ARG2)
449 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, i, rnd);
450 1.1 mrg #else
451 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, rnd);
452 1.1 mrg #endif
453 1.1.1.3 mrg flags = __gmpfr_flags;
454 1.1.1.3 mrg mpfr_set_emin (oemin);
455 1.1.1.3 mrg mpfr_set_emax (oemax);
456 1.1.1.3 mrg if (! (SAME_VAL (w, y) &&
457 1.1.1.3 mrg SAME_SIGN (inexact, compare) &&
458 1.1.1.3 mrg flags == oldflags))
459 1.1.1.3 mrg {
460 1.1.1.3 mrg printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
461 1.1.1.3 mrg ", reduced exponent range [%"
462 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
463 1.1.1.3 mrg (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
464 1.1.1.3 mrg printf ("x = ");
465 1.1.1.3 mrg mpfr_dump (x);
466 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
467 1.1.1.3 mrg printf ("u = ");
468 1.1.1.3 mrg mpfr_dump (u);
469 1.1.1.3 mrg #endif
470 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s\n",
471 1.1.1.3 mrg (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
472 1.1.1.3 mrg printf ("Expected:\n y = ");
473 1.1.1.3 mrg mpfr_dump (y);
474 1.1.1.3 mrg printf (" inex = %d, flags =", compare);
475 1.1.1.3 mrg flags_out (oldflags);
476 1.1.1.3 mrg printf ("Got:\n w = ");
477 1.1.1.3 mrg mpfr_dump (w);
478 1.1.1.3 mrg printf (" inex = %d, flags =", inexact);
479 1.1.1.3 mrg flags_out (flags);
480 1.1.1.3 mrg exit (1);
481 1.1.1.3 mrg }
482 1.1.1.3 mrg }
483 1.1.1.3 mrg __gmpfr_flags = oldflags; /* restore the flags */
484 1.1.1.3 mrg }
485 1.1.1.3 mrg
486 1.1 mrg if (MPFR_IS_SINGULAR (y))
487 1.1 mrg {
488 1.1 mrg if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
489 1.1.1.3 mrg TGENERIC_CHECK ("bad NaN flag",
490 1.1 mrg MPFR_IS_NAN (y) && mpfr_nanflag_p ());
491 1.1 mrg else if (MPFR_IS_INF (y))
492 1.1.1.2 mrg {
493 1.1.1.3 mrg TGENERIC_CHECK ("bad overflow flag",
494 1.1.1.2 mrg (compare != 0) ^ (mpfr_overflow_p () == 0));
495 1.1.1.3 mrg TGENERIC_CHECK ("bad divide-by-zero flag",
496 1.1.1.2 mrg (compare == 0 && !infinite_input) ^
497 1.1.1.2 mrg (mpfr_divby0_p () == 0));
498 1.1.1.2 mrg }
499 1.1 mrg else if (MPFR_IS_ZERO (y))
500 1.1.1.3 mrg TGENERIC_CHECK ("bad underflow flag",
501 1.1 mrg (compare != 0) ^ (mpfr_underflow_p () == 0));
502 1.1 mrg }
503 1.1.1.2 mrg else if (mpfr_divby0_p ())
504 1.1.1.2 mrg {
505 1.1.1.3 mrg TGENERIC_CHECK ("both overflow and divide-by-zero",
506 1.1.1.2 mrg ! mpfr_overflow_p ());
507 1.1.1.3 mrg TGENERIC_CHECK ("both underflow and divide-by-zero",
508 1.1.1.2 mrg ! mpfr_underflow_p ());
509 1.1.1.3 mrg TGENERIC_CHECK ("bad compare value (divide-by-zero)",
510 1.1.1.2 mrg compare == 0);
511 1.1.1.2 mrg }
512 1.1 mrg else if (mpfr_overflow_p ())
513 1.1 mrg {
514 1.1.1.3 mrg TGENERIC_CHECK ("both underflow and overflow",
515 1.1.1.2 mrg ! mpfr_underflow_p ());
516 1.1.1.3 mrg TGENERIC_CHECK ("bad compare value (overflow)", compare != 0);
517 1.1 mrg mpfr_nexttoinf (y);
518 1.1.1.3 mrg TGENERIC_CHECK ("should have been max MPFR number (overflow)",
519 1.1 mrg MPFR_IS_INF (y));
520 1.1 mrg }
521 1.1 mrg else if (mpfr_underflow_p ())
522 1.1 mrg {
523 1.1.1.3 mrg TGENERIC_CHECK ("bad compare value (underflow)", compare != 0);
524 1.1 mrg mpfr_nexttozero (y);
525 1.1.1.3 mrg TGENERIC_CHECK ("should have been min MPFR number (underflow)",
526 1.1 mrg MPFR_IS_ZERO (y));
527 1.1 mrg }
528 1.1 mrg else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
529 1.1 mrg {
530 1.1 mrg ctrn++;
531 1.1 mrg mpfr_set (t, y, rnd);
532 1.1 mrg /* Risk of failures are known when some flags are already set
533 1.1 mrg before the function call. Do not set the erange flag, as
534 1.1 mrg it will remain set after the function call and no checks
535 1.1 mrg are performed in such a case (see the mpfr_erangeflag_p
536 1.1 mrg test below). */
537 1.1 mrg if (randlimb () & 1)
538 1.1 mrg __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
539 1.1 mrg #ifdef DEBUG_TGENERIC
540 1.1 mrg TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
541 1.1 mrg #endif
542 1.1 mrg /* Let's increase the precision of the inputs in a random way.
543 1.1 mrg In most cases, this doesn't make any difference, but for
544 1.1 mrg the mpfr_fmod bug fixed in r6230, this triggers the bug. */
545 1.1 mrg mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
546 1.1 mrg MPFR_RNDN);
547 1.1 mrg #if defined(TWO_ARGS)
548 1.1 mrg mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
549 1.1 mrg MPFR_RNDN);
550 1.1 mrg inexact = TEST_FUNCTION (z, x, u, rnd);
551 1.1 mrg #elif defined(DOUBLE_ARG1)
552 1.1 mrg inexact = TEST_FUNCTION (z, d, x, rnd);
553 1.1 mrg #elif defined(DOUBLE_ARG2)
554 1.1 mrg inexact = TEST_FUNCTION (z, x, d, rnd);
555 1.1.1.3 mrg #elif defined(ULONG_ARG1)
556 1.1.1.3 mrg inexact = TEST_FUNCTION (z, i, x, rnd);
557 1.1.1.3 mrg #elif defined(ULONG_ARG2)
558 1.1.1.3 mrg inexact = TEST_FUNCTION (z, x, i, rnd);
559 1.1 mrg #else
560 1.1 mrg inexact = TEST_FUNCTION (z, x, rnd);
561 1.1 mrg #endif
562 1.1 mrg if (mpfr_erangeflag_p ())
563 1.1 mrg goto next_n;
564 1.1.1.3 mrg if (! mpfr_equal_p (t, z))
565 1.1 mrg {
566 1.1.1.3 mrg printf ("tgeneric: results differ for "
567 1.1.1.3 mrg MAKE_STR(TEST_FUNCTION) " on\n x = ");
568 1.1.1.3 mrg mpfr_dump (x);
569 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
570 1.1.1.3 mrg printf (" u = ");
571 1.1.1.3 mrg mpfr_dump (u);
572 1.1 mrg #endif
573 1.1.1.3 mrg printf (" prec = %u, rnd_mode = %s\n",
574 1.1.1.3 mrg (unsigned int) prec, mpfr_print_rnd_mode (rnd));
575 1.1.1.3 mrg printf ("Got ");
576 1.1.1.3 mrg mpfr_dump (z);
577 1.1.1.3 mrg printf ("Expected ");
578 1.1.1.3 mrg mpfr_dump (t);
579 1.1.1.3 mrg printf ("Approx ");
580 1.1.1.3 mrg mpfr_dump (y);
581 1.1 mrg exit (1);
582 1.1 mrg }
583 1.1 mrg compare2 = mpfr_cmp (t, y);
584 1.1 mrg /* if rounding to nearest, cannot know the sign of t - f(x)
585 1.1 mrg because of composed rounding: y = o(f(x)) and t = o(y) */
586 1.1 mrg if (compare * compare2 >= 0)
587 1.1 mrg compare = compare + compare2;
588 1.1 mrg else
589 1.1 mrg compare = inexact; /* cannot determine sign(t-f(x)) */
590 1.1.1.3 mrg if (! SAME_SIGN (inexact, compare))
591 1.1 mrg {
592 1.1 mrg printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
593 1.1 mrg "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
594 1.1.1.3 mrg printf ("x = ");
595 1.1.1.3 mrg mpfr_dump (x);
596 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
597 1.1.1.3 mrg printf ("u = ");
598 1.1.1.3 mrg mpfr_dump (u);
599 1.1 mrg #endif
600 1.1.1.3 mrg printf ("y = ");
601 1.1.1.3 mrg mpfr_dump (y);
602 1.1.1.3 mrg printf ("t = ");
603 1.1.1.3 mrg mpfr_dump (t);
604 1.1 mrg exit (1);
605 1.1 mrg }
606 1.1 mrg }
607 1.1 mrg else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
608 1.1 mrg {
609 1.1 mrg /* For developers only! */
610 1.1 mrg MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
611 1.1 mrg mpfr_nexttoinf (y);
612 1.1 mrg if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
613 1.1.1.2 mrg && !mpfr_overflow_p () && TGENERIC_SO_TEST)
614 1.1 mrg {
615 1.1 mrg printf ("Possible bug! |y| is the maximum finite number "
616 1.1 mrg "and has been obtained when\nrounding toward zero"
617 1.1 mrg " (%s). Thus there is a very probable overflow,\n"
618 1.1 mrg "but the overflow flag is not set!\n",
619 1.1 mrg mpfr_print_rnd_mode (rnd));
620 1.1.1.3 mrg printf ("x = ");
621 1.1.1.3 mrg mpfr_dump (x);
622 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
623 1.1.1.3 mrg printf ("u = ");
624 1.1.1.3 mrg mpfr_dump (u);
625 1.1 mrg #endif
626 1.1 mrg exit (1);
627 1.1 mrg }
628 1.1 mrg }
629 1.1 mrg
630 1.1 mrg next_n:
631 1.1 mrg /* In case the exponent range has been changed by
632 1.1 mrg tests_default_random() or for special values... */
633 1.1 mrg mpfr_set_emin (old_emin);
634 1.1 mrg mpfr_set_emax (old_emax);
635 1.1 mrg }
636 1.1 mrg }
637 1.1 mrg
638 1.1 mrg #ifndef TGENERIC_NOWARNING
639 1.1 mrg if (3 * ctrn < 2 * ctrt)
640 1.1 mrg printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
641 1.1 mrg ctrn, ctrt);
642 1.1 mrg #endif
643 1.1 mrg
644 1.1 mrg mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
645 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
646 1.1 mrg mpfr_clear (u);
647 1.1 mrg #endif
648 1.1 mrg }
649 1.1 mrg
650 1.1 mrg #undef TEST_RANDOM_POS
651 1.1 mrg #undef TEST_RANDOM_POS2
652 1.1 mrg #undef TEST_RANDOM_EMIN
653 1.1 mrg #undef TEST_RANDOM_EMAX
654 1.1.1.3 mrg #undef TEST_RANDOM_ALWAYS_SCALE
655 1.1 mrg #undef RAND_FUNCTION
656 1.1 mrg #undef TWO_ARGS
657 1.1.1.3 mrg #undef TWO_ARGS_ALL
658 1.1.1.3 mrg #undef DOUBLE_ARG1
659 1.1.1.3 mrg #undef DOUBLE_ARG2
660 1.1.1.3 mrg #undef ULONG_ARG1
661 1.1.1.3 mrg #undef ULONG_ARG2
662 1.1 mrg #undef TEST_FUNCTION
663 1.1 mrg #undef test_generic
664