tgeneric.c revision 1.1.1.3.2.1 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.2.1 pgoyette Copyright 2001-2018 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.2.1 pgoyette /* TODO: Add support for type long and extreme integer values, as done
31 1.1.1.3.2.1 pgoyette in tgeneric_ui.c; then tgeneric_ui.c could probably disappear. */
32 1.1.1.3.2.1 pgoyette
33 1.1.1.3.2.1 pgoyette #ifndef ONE_ARG
34 1.1.1.3 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) || \
35 1.1.1.3 mrg defined(ULONG_ARG1) || defined(ULONG_ARG2)
36 1.1.1.3 mrg #define TWO_ARGS_ALL
37 1.1.1.3 mrg #endif
38 1.1.1.3.2.1 pgoyette #endif
39 1.1.1.3.2.1 pgoyette
40 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS_ALL) || defined(ULONG_ARG1) || defined(ULONG_ARG2)
41 1.1.1.3.2.1 pgoyette #define NEED_U
42 1.1.1.3.2.1 pgoyette #endif
43 1.1 mrg
44 1.1 mrg #ifndef TEST_RANDOM_POS
45 1.1 mrg /* For the random function: one number on two is negative. */
46 1.1 mrg #define TEST_RANDOM_POS 256
47 1.1 mrg #endif
48 1.1 mrg
49 1.1 mrg #ifndef TEST_RANDOM_POS2
50 1.1 mrg /* For the random function: one number on two is negative. */
51 1.1 mrg #define TEST_RANDOM_POS2 256
52 1.1 mrg #endif
53 1.1 mrg
54 1.1 mrg #ifndef TEST_RANDOM_EMIN
55 1.1 mrg #define TEST_RANDOM_EMIN -256
56 1.1 mrg #endif
57 1.1 mrg
58 1.1 mrg #ifndef TEST_RANDOM_EMAX
59 1.1 mrg #define TEST_RANDOM_EMAX 255
60 1.1 mrg #endif
61 1.1 mrg
62 1.1.1.3 mrg #ifndef TEST_RANDOM_ALWAYS_SCALE
63 1.1.1.3 mrg #define TEST_RANDOM_ALWAYS_SCALE 0
64 1.1.1.3 mrg #endif
65 1.1.1.3 mrg
66 1.1.1.2 mrg /* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug,
67 1.1.1.2 mrg then define TGENERIC_SO_TEST with an adequate test (possibly 0) to
68 1.1.1.2 mrg omit this particular case. */
69 1.1.1.2 mrg #ifndef TGENERIC_SO_TEST
70 1.1.1.2 mrg #define TGENERIC_SO_TEST 1
71 1.1.1.2 mrg #endif
72 1.1.1.2 mrg
73 1.1 mrg /* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions
74 1.1.1.3.2.1 pgoyette * with 2 arguments. See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>.
75 1.1 mrg */
76 1.1 mrg #define TGENERIC_FAIL(S, X, U) \
77 1.1 mrg do \
78 1.1 mrg { \
79 1.1.1.3 mrg printf ("tgeneric: %s\nx = ", (S)); \
80 1.1.1.3 mrg mpfr_dump (X);; \
81 1.1.1.3 mrg if ((void *) (U) != 0) \
82 1.1 mrg { \
83 1.1 mrg printf ("u = "); \
84 1.1.1.3 mrg mpfr_dump (U); \
85 1.1 mrg } \
86 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s, inexact = %d\nflags =", \
87 1.1.1.3 mrg (unsigned int) yprec, mpfr_print_rnd_mode (rnd), \
88 1.1.1.3 mrg compare); \
89 1.1.1.3 mrg flags_out (flags); \
90 1.1 mrg exit (1); \
91 1.1 mrg } \
92 1.1 mrg while (0)
93 1.1 mrg
94 1.1.1.3 mrg #define TGENERIC_CHECK_AUX(S, EXPR, U) \
95 1.1.1.3 mrg do \
96 1.1.1.3 mrg if (!(EXPR)) \
97 1.1.1.3 mrg TGENERIC_FAIL (S " for " MAKE_STR(TEST_FUNCTION), x, U); \
98 1.1.1.2 mrg while (0)
99 1.1.1.2 mrg
100 1.1 mrg #undef TGENERIC_CHECK
101 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
102 1.1.1.2 mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u)
103 1.1 mrg #else
104 1.1.1.2 mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0)
105 1.1 mrg #endif
106 1.1 mrg
107 1.1.1.3.2.1 pgoyette #ifdef MPFR_DEBUG_TGENERIC
108 1.1 mrg #define TGENERIC_IAUX(F,P,X,U) \
109 1.1 mrg do \
110 1.1 mrg { \
111 1.1 mrg printf ("tgeneric: testing function " STR(F) \
112 1.1 mrg ", %s, target prec = %lu\nx = ", \
113 1.1 mrg mpfr_print_rnd_mode (rnd), (unsigned long) (P)); \
114 1.1.1.3 mrg mpfr_dump (X); \
115 1.1.1.3 mrg if ((void *) (U) != 0) \
116 1.1 mrg { \
117 1.1 mrg printf ("u = "); \
118 1.1.1.3 mrg mpfr_dump (U); \
119 1.1 mrg } \
120 1.1 mrg } \
121 1.1 mrg while (0)
122 1.1 mrg #undef TGENERIC_INFO
123 1.1.1.3 mrg #if defined(TWO_ARGS_ALL)
124 1.1 mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u)
125 1.1 mrg #else
126 1.1 mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0)
127 1.1 mrg #endif
128 1.1.1.3.2.1 pgoyette #endif /* MPFR_DEBUG_TGENERIC */
129 1.1 mrg
130 1.1 mrg /* For some functions (for example cos), the argument reduction is too
131 1.1 mrg expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX
132 1.1 mrg to some reasonable value before including tgeneric.c. */
133 1.1 mrg #ifndef REDUCE_EMAX
134 1.1 mrg #define REDUCE_EMAX mpfr_get_emax ()
135 1.1 mrg #endif
136 1.1 mrg
137 1.1.1.3.2.1 pgoyette /* same for mpfr_get_emin() */
138 1.1.1.3.2.1 pgoyette #ifndef REDUCE_EMIN
139 1.1.1.3.2.1 pgoyette #define REDUCE_EMIN mpfr_get_emin ()
140 1.1.1.3.2.1 pgoyette #endif
141 1.1.1.3.2.1 pgoyette
142 1.1 mrg static void
143 1.1.1.2 mrg test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
144 1.1 mrg {
145 1.1 mrg mpfr_prec_t prec, xprec, yprec;
146 1.1.1.3.2.1 pgoyette mpfr_t x, y, z, t, w, yd, yu;
147 1.1.1.3.2.1 pgoyette #ifdef NEED_U
148 1.1 mrg mpfr_t u;
149 1.1.1.3 mrg #endif
150 1.1.1.3 mrg #if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
151 1.1 mrg double d;
152 1.1 mrg #endif
153 1.1.1.3 mrg #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
154 1.1.1.3 mrg unsigned long i;
155 1.1.1.3 mrg #endif
156 1.1 mrg mpfr_rnd_t rnd;
157 1.1 mrg int inexact, compare, compare2;
158 1.1 mrg unsigned int n;
159 1.1 mrg unsigned long ctrt = 0, ctrn = 0;
160 1.1 mrg mpfr_exp_t old_emin, old_emax;
161 1.1 mrg
162 1.1 mrg old_emin = mpfr_get_emin ();
163 1.1 mrg old_emax = mpfr_get_emax ();
164 1.1 mrg
165 1.1.1.3.2.1 pgoyette mpfr_inits2 (MPFR_PREC_MIN, x, y, yd, yu, z, t, w, (mpfr_ptr) 0);
166 1.1.1.3.2.1 pgoyette #ifdef NEED_U
167 1.1 mrg mpfr_init2 (u, MPFR_PREC_MIN);
168 1.1 mrg #endif
169 1.1 mrg
170 1.1 mrg /* generic test */
171 1.1 mrg for (prec = p0; prec <= p1; prec++)
172 1.1 mrg {
173 1.1.1.3.2.1 pgoyette /* Number of overflow/underflow tests for each precision.
174 1.1.1.3.2.1 pgoyette Since MPFR uses several algorithms and there may also be
175 1.1.1.3.2.1 pgoyette early overflow/underflow detection, several tests may be
176 1.1.1.3.2.1 pgoyette needed to detect a bug. */
177 1.1.1.3.2.1 pgoyette int test_of = 3, test_uf = 3;
178 1.1.1.3.2.1 pgoyette
179 1.1 mrg mpfr_set_prec (z, prec);
180 1.1 mrg mpfr_set_prec (t, prec);
181 1.1 mrg yprec = prec + 10;
182 1.1 mrg mpfr_set_prec (y, yprec);
183 1.1.1.3.2.1 pgoyette mpfr_set_prec (yd, yprec);
184 1.1.1.3.2.1 pgoyette mpfr_set_prec (yu, yprec);
185 1.1 mrg mpfr_set_prec (w, yprec);
186 1.1 mrg
187 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
188 1.1.1.3.2.1 pgoyette #define NSPEC 9
189 1.1.1.3.2.1 pgoyette #else
190 1.1.1.3.2.1 pgoyette #define NSPEC 5
191 1.1.1.3.2.1 pgoyette #endif
192 1.1.1.3.2.1 pgoyette
193 1.1.1.3.2.1 pgoyette /* Note: in precision p1, we test NSPEC special cases. */
194 1.1.1.3.2.1 pgoyette for (n = 0; n < (prec == p1 ? nmax + NSPEC : nmax); n++)
195 1.1 mrg {
196 1.1.1.2 mrg int infinite_input = 0;
197 1.1.1.3.2.1 pgoyette mpfr_flags_t flags;
198 1.1.1.3 mrg mpfr_exp_t oemin, oemax;
199 1.1.1.2 mrg
200 1.1 mrg xprec = prec;
201 1.1 mrg if (randlimb () & 1)
202 1.1 mrg {
203 1.1.1.3 mrg /* In half cases, modify the precision of the inputs:
204 1.1.1.3 mrg If the base precision (for the result) is small,
205 1.1.1.3 mrg take a larger input precision in general, else
206 1.1.1.3 mrg take a smaller precision. */
207 1.1.1.3 mrg xprec *= (prec < 16 ? 256.0 : 1.0) *
208 1.1.1.3.2.1 pgoyette (double) randlimb () / MPFR_LIMB_MAX;
209 1.1 mrg if (xprec < MPFR_PREC_MIN)
210 1.1 mrg xprec = MPFR_PREC_MIN;
211 1.1 mrg }
212 1.1 mrg mpfr_set_prec (x, xprec);
213 1.1.1.3 mrg #if defined(TWO_ARGS)
214 1.1 mrg mpfr_set_prec (u, xprec);
215 1.1 mrg #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
216 1.1 mrg mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
217 1.1.1.3 mrg #elif defined(ULONG_ARG1) || defined(ULONG_ARG2)
218 1.1.1.3 mrg mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT);
219 1.1 mrg #endif
220 1.1 mrg
221 1.1.1.3.2.1 pgoyette if (n >= NSPEC || prec < p1)
222 1.1 mrg {
223 1.1 mrg #if defined(RAND_FUNCTION)
224 1.1 mrg RAND_FUNCTION (x);
225 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
226 1.1 mrg RAND_FUNCTION (u);
227 1.1 mrg #endif
228 1.1.1.3 mrg #else /* ! defined(RAND_FUNCTION) */
229 1.1 mrg tests_default_random (x, TEST_RANDOM_POS,
230 1.1.1.3 mrg TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
231 1.1.1.3 mrg TEST_RANDOM_ALWAYS_SCALE);
232 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
233 1.1 mrg tests_default_random (u, TEST_RANDOM_POS2,
234 1.1.1.3 mrg TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
235 1.1.1.3 mrg TEST_RANDOM_ALWAYS_SCALE);
236 1.1 mrg #endif
237 1.1.1.3 mrg #endif /* ! defined(RAND_FUNCTION) */
238 1.1 mrg }
239 1.1 mrg else
240 1.1 mrg {
241 1.1.1.3.2.1 pgoyette /* Special cases tested in precision p1 if n < NSPEC. They are
242 1.1 mrg useful really in the extended exponent range. */
243 1.1.1.2 mrg #if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
244 1.1.1.2 mrg goto next_n;
245 1.1.1.2 mrg #endif
246 1.1 mrg set_emin (MPFR_EMIN_MIN);
247 1.1 mrg set_emax (MPFR_EMAX_MAX);
248 1.1.1.3.2.1 pgoyette if (n == 0)
249 1.1 mrg {
250 1.1.1.3.2.1 pgoyette mpfr_set_nan (x);
251 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
252 1.1.1.3.2.1 pgoyette #if defined(RAND_FUNCTION)
253 1.1.1.3.2.1 pgoyette RAND_FUNCTION (u);
254 1.1.1.3.2.1 pgoyette #else
255 1.1.1.3.2.1 pgoyette tests_default_random (u, TEST_RANDOM_POS2,
256 1.1.1.3.2.1 pgoyette TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
257 1.1.1.3.2.1 pgoyette TEST_RANDOM_ALWAYS_SCALE);
258 1.1.1.3.2.1 pgoyette #endif
259 1.1.1.3.2.1 pgoyette #endif
260 1.1.1.3.2.1 pgoyette }
261 1.1.1.3.2.1 pgoyette else if (n <= 2)
262 1.1.1.3.2.1 pgoyette {
263 1.1.1.3.2.1 pgoyette MPFR_ASSERTN (n == 1 || n == 2);
264 1.1.1.3.2.1 pgoyette mpfr_set_si (x, n == 1 ? 1 : -1, MPFR_RNDN);
265 1.1.1.3.2.1 pgoyette mpfr_set_exp (x, REDUCE_EMIN);
266 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
267 1.1 mrg mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
268 1.1.1.3.2.1 pgoyette mpfr_set_exp (u, REDUCE_EMIN);
269 1.1 mrg #endif
270 1.1 mrg }
271 1.1.1.3.2.1 pgoyette else if (n <= 4)
272 1.1 mrg {
273 1.1.1.3.2.1 pgoyette MPFR_ASSERTN (n == 3 || n == 4);
274 1.1.1.3.2.1 pgoyette mpfr_set_si (x, n == 3 ? 1 : -1, MPFR_RNDN);
275 1.1 mrg mpfr_setmax (x, REDUCE_EMAX);
276 1.1 mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
277 1.1 mrg mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
278 1.1.1.3.2.1 pgoyette mpfr_setmax (u, REDUCE_EMAX);
279 1.1.1.3.2.1 pgoyette #endif
280 1.1.1.3.2.1 pgoyette }
281 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
282 1.1.1.3.2.1 pgoyette else if (n <= 6)
283 1.1.1.3.2.1 pgoyette {
284 1.1.1.3.2.1 pgoyette MPFR_ASSERTN (n == 5 || n == 6);
285 1.1.1.3.2.1 pgoyette mpfr_set_si (x, n == 5 ? 1 : -1, MPFR_RNDN);
286 1.1.1.3.2.1 pgoyette mpfr_set_exp (x, REDUCE_EMIN);
287 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
288 1.1.1.3.2.1 pgoyette mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
289 1.1.1.3.2.1 pgoyette mpfr_setmax (u, REDUCE_EMAX);
290 1.1 mrg #endif
291 1.1 mrg }
292 1.1.1.3.2.1 pgoyette else
293 1.1.1.3.2.1 pgoyette {
294 1.1.1.3.2.1 pgoyette MPFR_ASSERTN (n == 7 || n == 8);
295 1.1.1.3.2.1 pgoyette mpfr_set_si (x, n == 7 ? 1 : -1, MPFR_RNDN);
296 1.1.1.3.2.1 pgoyette mpfr_setmax (x, REDUCE_EMAX);
297 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
298 1.1.1.3.2.1 pgoyette mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
299 1.1.1.3.2.1 pgoyette mpfr_set_exp (u, REDUCE_EMIN);
300 1.1.1.3.2.1 pgoyette #endif
301 1.1.1.3.2.1 pgoyette }
302 1.1.1.3.2.1 pgoyette #endif /* two arguments */
303 1.1 mrg }
304 1.1 mrg
305 1.1.1.3 mrg #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
306 1.1.1.3 mrg i = randlimb ();
307 1.1.1.3 mrg inexact = mpfr_set_ui (u, i, MPFR_RNDN);
308 1.1.1.3 mrg MPFR_ASSERTN (inexact == 0);
309 1.1.1.3 mrg #endif
310 1.1.1.3 mrg
311 1.1.1.3 mrg /* Exponent range for the test. */
312 1.1.1.3 mrg oemin = mpfr_get_emin ();
313 1.1.1.3 mrg oemax = mpfr_get_emax ();
314 1.1.1.3 mrg
315 1.1 mrg rnd = RND_RAND ();
316 1.1 mrg mpfr_clear_flags ();
317 1.1.1.3.2.1 pgoyette #ifdef MPFR_DEBUG_TGENERIC
318 1.1 mrg TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
319 1.1 mrg #endif
320 1.1 mrg #if defined(TWO_ARGS)
321 1.1 mrg compare = TEST_FUNCTION (y, x, u, rnd);
322 1.1 mrg #elif defined(DOUBLE_ARG1)
323 1.1 mrg d = mpfr_get_d (u, rnd);
324 1.1 mrg compare = TEST_FUNCTION (y, d, x, rnd);
325 1.1.1.2 mrg /* d can be infinite due to overflow in mpfr_get_d */
326 1.1.1.2 mrg infinite_input |= DOUBLE_ISINF (d);
327 1.1 mrg #elif defined(DOUBLE_ARG2)
328 1.1 mrg d = mpfr_get_d (u, rnd);
329 1.1 mrg compare = TEST_FUNCTION (y, x, d, rnd);
330 1.1.1.2 mrg /* d can be infinite due to overflow in mpfr_get_d */
331 1.1.1.2 mrg infinite_input |= DOUBLE_ISINF (d);
332 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1) && defined(ONE_ARG)
333 1.1.1.3.2.1 pgoyette compare = TEST_FUNCTION (y, i, rnd);
334 1.1.1.3 mrg #elif defined(ULONG_ARG1)
335 1.1.1.3 mrg compare = TEST_FUNCTION (y, i, x, rnd);
336 1.1.1.3 mrg #elif defined(ULONG_ARG2)
337 1.1.1.3 mrg compare = TEST_FUNCTION (y, x, i, rnd);
338 1.1 mrg #else
339 1.1 mrg compare = TEST_FUNCTION (y, x, rnd);
340 1.1 mrg #endif
341 1.1.1.3 mrg flags = __gmpfr_flags;
342 1.1.1.3 mrg if (mpfr_get_emin () != oemin ||
343 1.1.1.3 mrg mpfr_get_emax () != oemax)
344 1.1.1.3 mrg {
345 1.1.1.3 mrg printf ("tgeneric: the exponent range has been modified"
346 1.1.1.3 mrg " by the tested function!\n");
347 1.1.1.3 mrg exit (1);
348 1.1.1.3 mrg }
349 1.1.1.3.2.1 pgoyette if (rnd != MPFR_RNDF)
350 1.1.1.3.2.1 pgoyette TGENERIC_CHECK ("bad inexact flag",
351 1.1.1.3.2.1 pgoyette (compare != 0) ^ (mpfr_inexflag_p () == 0));
352 1.1 mrg ctrt++;
353 1.1 mrg
354 1.1.1.3.2.1 pgoyette /* If rnd = RNDF, check that we obtain the same result as
355 1.1.1.3.2.1 pgoyette RNDD or RNDU. */
356 1.1.1.3.2.1 pgoyette if (rnd == MPFR_RNDF)
357 1.1.1.3.2.1 pgoyette {
358 1.1.1.3.2.1 pgoyette #if defined(TWO_ARGS)
359 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, x, u, MPFR_RNDD);
360 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, x, u, MPFR_RNDU);
361 1.1.1.3.2.1 pgoyette #elif defined(DOUBLE_ARG1)
362 1.1.1.3.2.1 pgoyette d = mpfr_get_d (u, MPFR_RNDD);
363 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, d, x, MPFR_RNDD);
364 1.1.1.3.2.1 pgoyette d = mpfr_get_d (u, MPFR_RNDU);
365 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, d, x, MPFR_RNDU);
366 1.1.1.3.2.1 pgoyette #elif defined(DOUBLE_ARG2)
367 1.1.1.3.2.1 pgoyette d = mpfr_get_d (u, MPFR_RNDD);
368 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, x, d, MPFR_RNDD);
369 1.1.1.3.2.1 pgoyette d = mpfr_get_d (u, MPFR_RNDU);
370 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, x, d, MPFR_RNDU);
371 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1) && defined(ONE_ARG)
372 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, i, MPFR_RNDD);
373 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, i, MPFR_RNDU);
374 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1)
375 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, i, x, MPFR_RNDD);
376 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, i, x, MPFR_RNDU);
377 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG2)
378 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, x, i, MPFR_RNDD);
379 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, x, i, MPFR_RNDU);
380 1.1.1.3.2.1 pgoyette #else
381 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yd, x, MPFR_RNDD);
382 1.1.1.3.2.1 pgoyette TEST_FUNCTION (yu, x, MPFR_RNDU);
383 1.1.1.3.2.1 pgoyette #endif
384 1.1.1.3.2.1 pgoyette if (! (SAME_VAL (y, yd) || SAME_VAL (y, yu)))
385 1.1.1.3.2.1 pgoyette {
386 1.1.1.3.2.1 pgoyette printf ("For RNDF, result does not match RNDD nor RNDU\n");
387 1.1.1.3.2.1 pgoyette printf ("x = "); mpfr_dump (x);
388 1.1.1.3.2.1 pgoyette #ifdef NEED_U
389 1.1.1.3.2.1 pgoyette printf ("u = "); mpfr_dump (u);
390 1.1.1.3.2.1 pgoyette #endif
391 1.1.1.3.2.1 pgoyette #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
392 1.1.1.3.2.1 pgoyette printf ("i = %lu\n", i);
393 1.1.1.3.2.1 pgoyette #endif
394 1.1.1.3.2.1 pgoyette printf ("yd (RNDD) = "); mpfr_dump (yd);
395 1.1.1.3.2.1 pgoyette printf ("yu (RNDU) = "); mpfr_dump (yu);
396 1.1.1.3.2.1 pgoyette printf ("y (RNDF) = "); mpfr_dump (y);
397 1.1.1.3.2.1 pgoyette exit (1);
398 1.1.1.3.2.1 pgoyette }
399 1.1.1.3.2.1 pgoyette }
400 1.1.1.3.2.1 pgoyette
401 1.1.1.3 mrg /* Tests in a reduced exponent range. */
402 1.1.1.3 mrg {
403 1.1.1.3.2.1 pgoyette mpfr_flags_t oldflags = flags;
404 1.1.1.3 mrg mpfr_exp_t e, emin, emax;
405 1.1.1.3 mrg
406 1.1.1.3 mrg /* Determine the smallest exponent range containing the
407 1.1.1.3 mrg exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
408 1.1.1.3 mrg and output (y). */
409 1.1.1.3 mrg emin = MPFR_EMAX_MAX;
410 1.1.1.3 mrg emax = MPFR_EMIN_MIN;
411 1.1.1.3 mrg if (MPFR_IS_PURE_FP (x))
412 1.1.1.3 mrg {
413 1.1.1.3 mrg e = MPFR_GET_EXP (x);
414 1.1.1.3 mrg if (e < emin)
415 1.1.1.3 mrg emin = e;
416 1.1.1.3 mrg if (e > emax)
417 1.1.1.3 mrg emax = e;
418 1.1.1.3 mrg }
419 1.1 mrg #if defined(TWO_ARGS)
420 1.1.1.3 mrg if (MPFR_IS_PURE_FP (u))
421 1.1.1.3 mrg {
422 1.1.1.3 mrg e = MPFR_GET_EXP (u);
423 1.1.1.3 mrg if (e < emin)
424 1.1.1.3 mrg emin = e;
425 1.1.1.3 mrg if (e > emax)
426 1.1.1.3 mrg emax = e;
427 1.1.1.3 mrg }
428 1.1.1.3 mrg #endif
429 1.1.1.3 mrg if (MPFR_IS_PURE_FP (y))
430 1.1.1.3 mrg {
431 1.1.1.3.2.1 pgoyette e = MPFR_GET_EXP (y); /* exponent of the result */
432 1.1.1.3.2.1 pgoyette
433 1.1.1.3.2.1 pgoyette if (test_of > 0 && e - 1 >= emax) /* overflow test */
434 1.1.1.3 mrg {
435 1.1.1.3.2.1 pgoyette mpfr_flags_t ex_flags;
436 1.1.1.3 mrg
437 1.1.1.3.2.1 pgoyette /* Exponent e of the result > exponents of the inputs;
438 1.1.1.3.2.1 pgoyette let's set emax to e - 1, so that one should get an
439 1.1.1.3.2.1 pgoyette overflow. */
440 1.1.1.3 mrg mpfr_set_emax (e - 1);
441 1.1.1.3.2.1 pgoyette #ifdef MPFR_DEBUG_TGENERIC
442 1.1.1.3.2.1 pgoyette printf ("tgeneric: overflow test (emax = %"
443 1.1.1.3.2.1 pgoyette MPFR_EXP_FSPEC "d)\n",
444 1.1.1.3.2.1 pgoyette (mpfr_eexp_t) __gmpfr_emax);
445 1.1.1.3.2.1 pgoyette #endif
446 1.1.1.3 mrg mpfr_clear_flags ();
447 1.1.1.3 mrg #if defined(TWO_ARGS)
448 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, u, rnd);
449 1.1.1.3 mrg #elif defined(DOUBLE_ARG1)
450 1.1.1.3 mrg inexact = TEST_FUNCTION (w, d, x, rnd);
451 1.1.1.3 mrg #elif defined(DOUBLE_ARG2)
452 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, d, rnd);
453 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1) && defined(ONE_ARG)
454 1.1.1.3.2.1 pgoyette inexact = TEST_FUNCTION (w, i, rnd);
455 1.1.1.3 mrg #elif defined(ULONG_ARG1)
456 1.1.1.3 mrg inexact = TEST_FUNCTION (w, i, x, rnd);
457 1.1.1.3 mrg #elif defined(ULONG_ARG2)
458 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, i, rnd);
459 1.1.1.3 mrg #else
460 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, rnd);
461 1.1.1.3 mrg #endif
462 1.1.1.3 mrg flags = __gmpfr_flags;
463 1.1.1.3 mrg mpfr_set_emax (oemax);
464 1.1.1.3 mrg ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
465 1.1.1.3.2.1 pgoyette /* For RNDF, this test makes no sense, since RNDF
466 1.1.1.3.2.1 pgoyette might return either the maximal floating-point
467 1.1.1.3.2.1 pgoyette value or infinity, and the flags might differ in
468 1.1.1.3.2.1 pgoyette those two cases. */
469 1.1.1.3.2.1 pgoyette if (flags != ex_flags && rnd != MPFR_RNDF)
470 1.1.1.3 mrg {
471 1.1.1.3 mrg printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
472 1.1.1.3 mrg ", reduced exponent range [%"
473 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
474 1.1.1.3 mrg "d] (overflow test) on:\n",
475 1.1.1.3 mrg (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
476 1.1.1.3 mrg printf ("x = ");
477 1.1.1.3 mrg mpfr_dump (x);
478 1.1.1.3.2.1 pgoyette #ifdef NEED_U
479 1.1.1.3 mrg printf ("u = ");
480 1.1.1.3 mrg mpfr_dump (u);
481 1.1.1.3 mrg #endif
482 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s\n",
483 1.1.1.3 mrg (unsigned int) yprec,
484 1.1.1.3 mrg mpfr_print_rnd_mode (rnd));
485 1.1.1.3 mrg printf ("Expected flags =");
486 1.1.1.3 mrg flags_out (ex_flags);
487 1.1.1.3 mrg printf (" got flags =");
488 1.1.1.3 mrg flags_out (flags);
489 1.1.1.3 mrg printf ("inex = %d, w = ", inexact);
490 1.1.1.3 mrg mpfr_dump (w);
491 1.1.1.3 mrg exit (1);
492 1.1.1.3 mrg }
493 1.1.1.3.2.1 pgoyette test_of--;
494 1.1.1.3 mrg }
495 1.1.1.3.2.1 pgoyette
496 1.1.1.3.2.1 pgoyette if (test_uf > 0 && e + 1 <= emin) /* underflow test */
497 1.1.1.3 mrg {
498 1.1.1.3.2.1 pgoyette mpfr_flags_t ex_flags;
499 1.1.1.3 mrg
500 1.1.1.3.2.1 pgoyette /* Exponent e of the result < exponents of the inputs;
501 1.1.1.3.2.1 pgoyette let's set emin to e + 1, so that one should get an
502 1.1.1.3.2.1 pgoyette underflow. */
503 1.1.1.3 mrg mpfr_set_emin (e + 1);
504 1.1.1.3.2.1 pgoyette #ifdef MPFR_DEBUG_TGENERIC
505 1.1.1.3.2.1 pgoyette printf ("tgeneric: underflow test (emin = %"
506 1.1.1.3.2.1 pgoyette MPFR_EXP_FSPEC "d)\n",
507 1.1.1.3.2.1 pgoyette (mpfr_eexp_t) __gmpfr_emin);
508 1.1.1.3.2.1 pgoyette #endif
509 1.1.1.3 mrg mpfr_clear_flags ();
510 1.1.1.3 mrg #if defined(TWO_ARGS)
511 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, u, rnd);
512 1.1.1.3 mrg #elif defined(DOUBLE_ARG1)
513 1.1.1.3 mrg inexact = TEST_FUNCTION (w, d, x, rnd);
514 1.1.1.3 mrg #elif defined(DOUBLE_ARG2)
515 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, d, rnd);
516 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1) && defined(ONE_ARG)
517 1.1.1.3.2.1 pgoyette inexact = TEST_FUNCTION (w, i, rnd);
518 1.1.1.3 mrg #elif defined(ULONG_ARG1)
519 1.1.1.3 mrg inexact = TEST_FUNCTION (w, i, x, rnd);
520 1.1.1.3 mrg #elif defined(ULONG_ARG2)
521 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, i, rnd);
522 1.1.1.3 mrg #else
523 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, rnd);
524 1.1 mrg #endif
525 1.1.1.3 mrg flags = __gmpfr_flags;
526 1.1.1.3 mrg mpfr_set_emin (oemin);
527 1.1.1.3 mrg ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
528 1.1.1.3.2.1 pgoyette /* For RNDF, this test makes no sense, since RNDF
529 1.1.1.3.2.1 pgoyette might return either the maximal floating-point
530 1.1.1.3.2.1 pgoyette value or infinity, and the flags might differ in
531 1.1.1.3.2.1 pgoyette those two cases. */
532 1.1.1.3.2.1 pgoyette if (flags != ex_flags && rnd != MPFR_RNDF)
533 1.1.1.3 mrg {
534 1.1.1.3 mrg printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
535 1.1.1.3 mrg ", reduced exponent range [%"
536 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
537 1.1.1.3 mrg "d] (underflow test) on:\n",
538 1.1.1.3 mrg (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
539 1.1.1.3 mrg printf ("x = ");
540 1.1.1.3 mrg mpfr_dump (x);
541 1.1.1.3.2.1 pgoyette #ifdef NEED_U
542 1.1.1.3 mrg printf ("u = ");
543 1.1.1.3 mrg mpfr_dump (u);
544 1.1.1.3 mrg #endif
545 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s\n",
546 1.1.1.3 mrg (unsigned int) yprec,
547 1.1.1.3 mrg mpfr_print_rnd_mode (rnd));
548 1.1.1.3 mrg printf ("Expected flags =");
549 1.1.1.3 mrg flags_out (ex_flags);
550 1.1.1.3 mrg printf (" got flags =");
551 1.1.1.3 mrg flags_out (flags);
552 1.1.1.3 mrg printf ("inex = %d, w = ", inexact);
553 1.1.1.3 mrg mpfr_dump (w);
554 1.1.1.3 mrg exit (1);
555 1.1.1.3 mrg }
556 1.1.1.3.2.1 pgoyette test_uf--;
557 1.1.1.3 mrg }
558 1.1.1.3.2.1 pgoyette
559 1.1.1.3 mrg if (e < emin)
560 1.1.1.3 mrg emin = e;
561 1.1.1.3 mrg if (e > emax)
562 1.1.1.3 mrg emax = e;
563 1.1.1.3.2.1 pgoyette } /* MPFR_IS_PURE_FP (y) */
564 1.1.1.3.2.1 pgoyette
565 1.1.1.3 mrg if (emin > emax)
566 1.1.1.3 mrg emin = emax; /* case where all values are singular */
567 1.1.1.3.2.1 pgoyette
568 1.1.1.3 mrg /* Consistency test in a reduced exponent range. Doing it
569 1.1.1.3 mrg for the first 10 samples and for prec == p1 (which has
570 1.1.1.3 mrg some special cases) should be sufficient. */
571 1.1.1.3 mrg if (ctrt <= 10 || prec == p1)
572 1.1.1.3 mrg {
573 1.1.1.3 mrg mpfr_set_emin (emin);
574 1.1.1.3 mrg mpfr_set_emax (emax);
575 1.1.1.3.2.1 pgoyette #ifdef MPFR_DEBUG_TGENERIC
576 1.1.1.3 mrg /* Useful information in case of assertion failure. */
577 1.1.1.3 mrg printf ("tgeneric: reduced exponent range [%"
578 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
579 1.1.1.3 mrg (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
580 1.1.1.2 mrg #endif
581 1.1.1.3 mrg mpfr_clear_flags ();
582 1.1 mrg #if defined(TWO_ARGS)
583 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, u, rnd);
584 1.1 mrg #elif defined(DOUBLE_ARG1)
585 1.1.1.3 mrg inexact = TEST_FUNCTION (w, d, x, rnd);
586 1.1 mrg #elif defined(DOUBLE_ARG2)
587 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, d, rnd);
588 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1) && defined(ONE_ARG)
589 1.1.1.3.2.1 pgoyette inexact = TEST_FUNCTION (w, i, rnd);
590 1.1.1.3 mrg #elif defined(ULONG_ARG1)
591 1.1.1.3 mrg inexact = TEST_FUNCTION (w, i, x, rnd);
592 1.1.1.3 mrg #elif defined(ULONG_ARG2)
593 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, i, rnd);
594 1.1 mrg #else
595 1.1.1.3 mrg inexact = TEST_FUNCTION (w, x, rnd);
596 1.1 mrg #endif
597 1.1.1.3 mrg flags = __gmpfr_flags;
598 1.1.1.3 mrg mpfr_set_emin (oemin);
599 1.1.1.3 mrg mpfr_set_emax (oemax);
600 1.1.1.3.2.1 pgoyette /* That test makes no sense for RNDF. */
601 1.1.1.3.2.1 pgoyette if (rnd != MPFR_RNDF && ! (SAME_VAL (w, y) &&
602 1.1.1.3 mrg SAME_SIGN (inexact, compare) &&
603 1.1.1.3 mrg flags == oldflags))
604 1.1.1.3 mrg {
605 1.1.1.3 mrg printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
606 1.1.1.3 mrg ", reduced exponent range [%"
607 1.1.1.3 mrg MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
608 1.1.1.3 mrg (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
609 1.1.1.3 mrg printf ("x = ");
610 1.1.1.3 mrg mpfr_dump (x);
611 1.1.1.3.2.1 pgoyette #ifdef NEED_U
612 1.1.1.3 mrg printf ("u = ");
613 1.1.1.3 mrg mpfr_dump (u);
614 1.1.1.3 mrg #endif
615 1.1.1.3 mrg printf ("yprec = %u, rnd_mode = %s\n",
616 1.1.1.3 mrg (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
617 1.1.1.3 mrg printf ("Expected:\n y = ");
618 1.1.1.3 mrg mpfr_dump (y);
619 1.1.1.3 mrg printf (" inex = %d, flags =", compare);
620 1.1.1.3 mrg flags_out (oldflags);
621 1.1.1.3 mrg printf ("Got:\n w = ");
622 1.1.1.3 mrg mpfr_dump (w);
623 1.1.1.3 mrg printf (" inex = %d, flags =", inexact);
624 1.1.1.3 mrg flags_out (flags);
625 1.1.1.3 mrg exit (1);
626 1.1.1.3 mrg }
627 1.1.1.3 mrg }
628 1.1.1.3.2.1 pgoyette
629 1.1.1.3 mrg __gmpfr_flags = oldflags; /* restore the flags */
630 1.1.1.3.2.1 pgoyette } /* tests in a reduced exponent range */
631 1.1.1.3 mrg
632 1.1 mrg if (MPFR_IS_SINGULAR (y))
633 1.1 mrg {
634 1.1 mrg if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
635 1.1.1.3 mrg TGENERIC_CHECK ("bad NaN flag",
636 1.1 mrg MPFR_IS_NAN (y) && mpfr_nanflag_p ());
637 1.1 mrg else if (MPFR_IS_INF (y))
638 1.1.1.2 mrg {
639 1.1.1.3 mrg TGENERIC_CHECK ("bad overflow flag",
640 1.1.1.2 mrg (compare != 0) ^ (mpfr_overflow_p () == 0));
641 1.1.1.3 mrg TGENERIC_CHECK ("bad divide-by-zero flag",
642 1.1.1.2 mrg (compare == 0 && !infinite_input) ^
643 1.1.1.2 mrg (mpfr_divby0_p () == 0));
644 1.1.1.2 mrg }
645 1.1 mrg else if (MPFR_IS_ZERO (y))
646 1.1.1.3 mrg TGENERIC_CHECK ("bad underflow flag",
647 1.1 mrg (compare != 0) ^ (mpfr_underflow_p () == 0));
648 1.1 mrg }
649 1.1.1.2 mrg else if (mpfr_divby0_p ())
650 1.1.1.2 mrg {
651 1.1.1.3 mrg TGENERIC_CHECK ("both overflow and divide-by-zero",
652 1.1.1.2 mrg ! mpfr_overflow_p ());
653 1.1.1.3 mrg TGENERIC_CHECK ("both underflow and divide-by-zero",
654 1.1.1.2 mrg ! mpfr_underflow_p ());
655 1.1.1.3 mrg TGENERIC_CHECK ("bad compare value (divide-by-zero)",
656 1.1.1.2 mrg compare == 0);
657 1.1.1.2 mrg }
658 1.1 mrg else if (mpfr_overflow_p ())
659 1.1 mrg {
660 1.1.1.3 mrg TGENERIC_CHECK ("both underflow and overflow",
661 1.1.1.2 mrg ! mpfr_underflow_p ());
662 1.1.1.3 mrg TGENERIC_CHECK ("bad compare value (overflow)", compare != 0);
663 1.1 mrg mpfr_nexttoinf (y);
664 1.1.1.3 mrg TGENERIC_CHECK ("should have been max MPFR number (overflow)",
665 1.1 mrg MPFR_IS_INF (y));
666 1.1 mrg }
667 1.1 mrg else if (mpfr_underflow_p ())
668 1.1 mrg {
669 1.1.1.3 mrg TGENERIC_CHECK ("bad compare value (underflow)", compare != 0);
670 1.1 mrg mpfr_nexttozero (y);
671 1.1.1.3 mrg TGENERIC_CHECK ("should have been min MPFR number (underflow)",
672 1.1 mrg MPFR_IS_ZERO (y));
673 1.1 mrg }
674 1.1.1.3.2.1 pgoyette else if (compare == 0 || rnd == MPFR_RNDF ||
675 1.1.1.3.2.1 pgoyette mpfr_can_round (y, yprec, rnd, rnd, prec))
676 1.1 mrg {
677 1.1 mrg ctrn++;
678 1.1 mrg mpfr_set (t, y, rnd);
679 1.1 mrg /* Risk of failures are known when some flags are already set
680 1.1 mrg before the function call. Do not set the erange flag, as
681 1.1 mrg it will remain set after the function call and no checks
682 1.1 mrg are performed in such a case (see the mpfr_erangeflag_p
683 1.1 mrg test below). */
684 1.1 mrg if (randlimb () & 1)
685 1.1 mrg __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
686 1.1.1.3.2.1 pgoyette #ifdef MPFR_DEBUG_TGENERIC
687 1.1 mrg TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
688 1.1 mrg #endif
689 1.1 mrg /* Let's increase the precision of the inputs in a random way.
690 1.1 mrg In most cases, this doesn't make any difference, but for
691 1.1 mrg the mpfr_fmod bug fixed in r6230, this triggers the bug. */
692 1.1 mrg mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
693 1.1 mrg MPFR_RNDN);
694 1.1 mrg #if defined(TWO_ARGS)
695 1.1 mrg mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
696 1.1 mrg MPFR_RNDN);
697 1.1 mrg inexact = TEST_FUNCTION (z, x, u, rnd);
698 1.1 mrg #elif defined(DOUBLE_ARG1)
699 1.1 mrg inexact = TEST_FUNCTION (z, d, x, rnd);
700 1.1 mrg #elif defined(DOUBLE_ARG2)
701 1.1 mrg inexact = TEST_FUNCTION (z, x, d, rnd);
702 1.1.1.3.2.1 pgoyette #elif defined(ULONG_ARG1) && defined(ONE_ARG)
703 1.1.1.3.2.1 pgoyette inexact = TEST_FUNCTION (z, i, rnd);
704 1.1.1.3 mrg #elif defined(ULONG_ARG1)
705 1.1.1.3 mrg inexact = TEST_FUNCTION (z, i, x, rnd);
706 1.1.1.3 mrg #elif defined(ULONG_ARG2)
707 1.1.1.3 mrg inexact = TEST_FUNCTION (z, x, i, rnd);
708 1.1 mrg #else
709 1.1 mrg inexact = TEST_FUNCTION (z, x, rnd);
710 1.1 mrg #endif
711 1.1 mrg if (mpfr_erangeflag_p ())
712 1.1 mrg goto next_n;
713 1.1.1.3.2.1 pgoyette if (! mpfr_equal_p (t, z) && rnd != MPFR_RNDF)
714 1.1 mrg {
715 1.1.1.3 mrg printf ("tgeneric: results differ for "
716 1.1.1.3 mrg MAKE_STR(TEST_FUNCTION) " on\n x = ");
717 1.1.1.3 mrg mpfr_dump (x);
718 1.1.1.3.2.1 pgoyette #ifdef NEED_U
719 1.1.1.3 mrg printf (" u = ");
720 1.1.1.3 mrg mpfr_dump (u);
721 1.1 mrg #endif
722 1.1.1.3 mrg printf (" prec = %u, rnd_mode = %s\n",
723 1.1.1.3 mrg (unsigned int) prec, mpfr_print_rnd_mode (rnd));
724 1.1.1.3 mrg printf ("Got ");
725 1.1.1.3 mrg mpfr_dump (z);
726 1.1.1.3 mrg printf ("Expected ");
727 1.1.1.3 mrg mpfr_dump (t);
728 1.1.1.3 mrg printf ("Approx ");
729 1.1.1.3 mrg mpfr_dump (y);
730 1.1 mrg exit (1);
731 1.1 mrg }
732 1.1 mrg compare2 = mpfr_cmp (t, y);
733 1.1 mrg /* if rounding to nearest, cannot know the sign of t - f(x)
734 1.1 mrg because of composed rounding: y = o(f(x)) and t = o(y) */
735 1.1 mrg if (compare * compare2 >= 0)
736 1.1 mrg compare = compare + compare2;
737 1.1 mrg else
738 1.1 mrg compare = inexact; /* cannot determine sign(t-f(x)) */
739 1.1.1.3.2.1 pgoyette if (! SAME_SIGN (inexact, compare) && rnd != MPFR_RNDF)
740 1.1 mrg {
741 1.1 mrg printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
742 1.1 mrg "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
743 1.1.1.3 mrg printf ("x = ");
744 1.1.1.3 mrg mpfr_dump (x);
745 1.1.1.3.2.1 pgoyette #ifdef NEED_U
746 1.1.1.3 mrg printf ("u = ");
747 1.1.1.3 mrg mpfr_dump (u);
748 1.1 mrg #endif
749 1.1.1.3 mrg printf ("y = ");
750 1.1.1.3 mrg mpfr_dump (y);
751 1.1.1.3 mrg printf ("t = ");
752 1.1.1.3 mrg mpfr_dump (t);
753 1.1 mrg exit (1);
754 1.1 mrg }
755 1.1 mrg }
756 1.1 mrg else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
757 1.1 mrg {
758 1.1 mrg /* For developers only! */
759 1.1 mrg MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
760 1.1 mrg mpfr_nexttoinf (y);
761 1.1 mrg if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
762 1.1.1.2 mrg && !mpfr_overflow_p () && TGENERIC_SO_TEST)
763 1.1 mrg {
764 1.1 mrg printf ("Possible bug! |y| is the maximum finite number "
765 1.1 mrg "and has been obtained when\nrounding toward zero"
766 1.1 mrg " (%s). Thus there is a very probable overflow,\n"
767 1.1 mrg "but the overflow flag is not set!\n",
768 1.1 mrg mpfr_print_rnd_mode (rnd));
769 1.1.1.3 mrg printf ("x = ");
770 1.1.1.3 mrg mpfr_dump (x);
771 1.1.1.3.2.1 pgoyette #ifdef NEED_U
772 1.1.1.3 mrg printf ("u = ");
773 1.1.1.3 mrg mpfr_dump (u);
774 1.1 mrg #endif
775 1.1 mrg exit (1);
776 1.1 mrg }
777 1.1 mrg }
778 1.1 mrg
779 1.1 mrg next_n:
780 1.1 mrg /* In case the exponent range has been changed by
781 1.1 mrg tests_default_random() or for special values... */
782 1.1 mrg mpfr_set_emin (old_emin);
783 1.1 mrg mpfr_set_emax (old_emax);
784 1.1 mrg }
785 1.1 mrg }
786 1.1 mrg
787 1.1 mrg #ifndef TGENERIC_NOWARNING
788 1.1 mrg if (3 * ctrn < 2 * ctrt)
789 1.1 mrg printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
790 1.1 mrg ctrn, ctrt);
791 1.1 mrg #endif
792 1.1 mrg
793 1.1.1.3.2.1 pgoyette mpfr_clears (x, y, yd, yu, z, t, w, (mpfr_ptr) 0);
794 1.1.1.3.2.1 pgoyette #ifdef NEED_U
795 1.1 mrg mpfr_clear (u);
796 1.1 mrg #endif
797 1.1 mrg }
798 1.1 mrg
799 1.1 mrg #undef TEST_RANDOM_POS
800 1.1 mrg #undef TEST_RANDOM_POS2
801 1.1 mrg #undef TEST_RANDOM_EMIN
802 1.1 mrg #undef TEST_RANDOM_EMAX
803 1.1.1.3 mrg #undef TEST_RANDOM_ALWAYS_SCALE
804 1.1 mrg #undef RAND_FUNCTION
805 1.1 mrg #undef TWO_ARGS
806 1.1.1.3 mrg #undef TWO_ARGS_ALL
807 1.1.1.3.2.1 pgoyette #undef NEED_U
808 1.1.1.3 mrg #undef DOUBLE_ARG1
809 1.1.1.3 mrg #undef DOUBLE_ARG2
810 1.1.1.3 mrg #undef ULONG_ARG1
811 1.1.1.3 mrg #undef ULONG_ARG2
812 1.1 mrg #undef TEST_FUNCTION
813 1.1 mrg #undef test_generic
814 1.1.1.3.2.1 pgoyette #undef NSPEC
815