tgmpop.c revision 1.1.1.3.4.1 1 /* Test file for mpfr_add_[q,z], mpfr_sub_[q,z], mpfr_div_[q,z],
2 mpfr_mul_[q,z], mpfr_cmp_[f,q,z]
3
4 Copyright 2004-2018 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6
7 This file is part of the GNU MPFR Library.
8
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24 #include "mpfr-test.h"
25
26 #ifndef MPFR_USE_MINI_GMP
27
28 #define CHECK_FOR(str, cond) \
29 if ((cond) == 0) { \
30 printf ("Special case error %s. Ternary value = %d, flags = %u\n", \
31 str, res, __gmpfr_flags); \
32 printf ("Got "); mpfr_dump (y); \
33 printf ("X = "); mpfr_dump (x); \
34 printf ("Q = "); mpz_out_str (stdout, 10, mpq_numref(q)); \
35 printf ("\n /"); mpz_out_str (stdout, 10, mpq_denref(q)); \
36 printf ("\n"); \
37 exit (1); \
38 }
39
40 #define CHECK_FORZ(str, cond) \
41 if ((cond) == 0) { \
42 printf ("Special case error %s. Ternary value = %d, flags = %u\n", \
43 str, res, __gmpfr_flags); \
44 printf ("Got "); mpfr_dump (y); \
45 printf ("X = "); mpfr_dump (x); \
46 printf ("Z = "); mpz_out_str (stdout, 10, z); \
47 printf ("\n"); \
48 exit (1); \
49 }
50
51 static void
52 special (void)
53 {
54 mpfr_t x, y;
55 mpq_t q;
56 mpz_t z;
57 int res = 0;
58
59 mpfr_init (x);
60 mpfr_init (y);
61 mpq_init (q);
62 mpz_init (z);
63
64 /* cancellation in mpfr_add_q */
65 mpfr_set_prec (x, 60);
66 mpfr_set_prec (y, 20);
67 mpz_set_str (mpq_numref (q), "-187207494", 10);
68 mpz_set_str (mpq_denref (q), "5721", 10);
69 mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44");
70 mpfr_add_q (y, x, q, MPFR_RNDN);
71 CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0);
72
73 mpfr_set_prec (x, 19);
74 mpfr_set_str_binary (x, "0.1011110101110011100E0");
75 mpz_set_str (mpq_numref (q), "187207494", 10);
76 mpz_set_str (mpq_denref (q), "5721", 10);
77 mpfr_set_prec (y, 29);
78 mpfr_add_q (y, x, q, MPFR_RNDD);
79 mpfr_set_prec (x, 29);
80 mpfr_set_str_binary (x, "11111111101001110011010001001E-14");
81 CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0);
82
83 /* Inf */
84 mpfr_set_inf (x, 1);
85 mpz_set_str (mpq_numref (q), "395877315", 10);
86 mpz_set_str (mpq_denref (q), "3508975966", 10);
87 mpfr_set_prec (y, 118);
88 mpfr_add_q (y, x, q, MPFR_RNDU);
89 CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
90 mpfr_sub_q (y, x, q, MPFR_RNDU);
91 CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
92
93 /* Nan */
94 MPFR_SET_NAN (x);
95 mpfr_add_q (y, x, q, MPFR_RNDU);
96 CHECK_FOR ("nan", mpfr_nan_p (y));
97 mpfr_sub_q (y, x, q, MPFR_RNDU);
98 CHECK_FOR ("nan", mpfr_nan_p (y));
99
100 /* Exact value */
101 mpfr_set_prec (x, 60);
102 mpfr_set_prec (y, 60);
103 mpfr_set_str1 (x, "0.5");
104 mpz_set_str (mpq_numref (q), "3", 10);
105 mpz_set_str (mpq_denref (q), "2", 10);
106 res = mpfr_add_q (y, x, q, MPFR_RNDU);
107 CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0);
108 res = mpfr_sub_q (y, x, q, MPFR_RNDU);
109 CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0);
110
111 /* Inf Rationnal */
112 mpq_set_ui (q, 1, 0);
113 mpfr_set_str1 (x, "0.5");
114 res = mpfr_add_q (y, x, q, MPFR_RNDN);
115 CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0);
116 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
117 CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0);
118 mpq_set_si (q, -1, 0);
119 res = mpfr_add_q (y, x, q, MPFR_RNDN);
120 CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0);
121 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
122 CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0);
123 res = mpfr_div_q (y, x, q, MPFR_RNDN);
124 CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_IS_NEG (y) && res == 0);
125 mpq_set_ui (q, 1, 0);
126 mpfr_set_inf (x, 1);
127 res = mpfr_add_q (y, x, q, MPFR_RNDN);
128 CHECK_FOR ("+Inf + +Inf", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0);
129 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
130 CHECK_FOR ("+Inf - +Inf", MPFR_IS_NAN (y) && res == 0);
131 mpfr_set_inf (x, -1);
132 res = mpfr_add_q (y, x, q, MPFR_RNDN);
133 CHECK_FOR ("-Inf + +Inf", MPFR_IS_NAN (y) && res == 0);
134 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
135 CHECK_FOR ("-Inf - +Inf", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0);
136 mpq_set_si (q, -1, 0);
137 mpfr_set_inf (x, 1);
138 res = mpfr_add_q (y, x, q, MPFR_RNDN);
139 CHECK_FOR ("+Inf + -Inf", MPFR_IS_NAN (y) && res == 0);
140 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
141 CHECK_FOR ("+Inf - -Inf", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0);
142 mpfr_set_inf (x, -1);
143 res = mpfr_add_q (y, x, q, MPFR_RNDN);
144 CHECK_FOR ("-Inf + -Inf", mpfr_inf_p (y) && MPFR_IS_NEG (y) && res == 0);
145 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
146 CHECK_FOR ("-Inf - -Inf", MPFR_IS_NAN (y) && res == 0);
147
148 /* 0 */
149 mpq_set_ui (q, 0, 1);
150 mpfr_set_ui (x, 42, MPFR_RNDN);
151 res = mpfr_add_q (y, x, q, MPFR_RNDN);
152 CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
153 res = mpfr_sub_q (y, x, q, MPFR_RNDN);
154 CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
155 res = mpfr_mul_q (y, x, q, MPFR_RNDN);
156 CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_IS_POS (y) && res == 0);
157 mpfr_clear_flags ();
158 res = mpfr_div_q (y, x, q, MPFR_RNDN);
159 CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0
160 && mpfr_divby0_p ());
161 mpz_set_ui (z, 0);
162 mpfr_clear_flags ();
163 res = mpfr_div_z (y, x, z, MPFR_RNDN);
164 CHECK_FORZ ("42/0", mpfr_inf_p (y) && MPFR_IS_POS (y) && res == 0
165 && mpfr_divby0_p ());
166
167 mpz_clear (z);
168 mpq_clear (q);
169 mpfr_clear (x);
170 mpfr_clear (y);
171 }
172
173 static void
174 check_for_zero (void)
175 {
176 /* Check that 0 is unsigned! */
177 mpq_t q;
178 mpz_t z;
179 mpfr_t x;
180 int r;
181 mpfr_sign_t i;
182
183 mpfr_init (x);
184 mpz_init (z);
185 mpq_init (q);
186
187 mpz_set_ui (z, 0);
188 mpq_set_ui (q, 0, 1);
189
190 MPFR_SET_ZERO (x);
191 RND_LOOP (r)
192 {
193 for (i = MPFR_SIGN_NEG ; i <= MPFR_SIGN_POS ;
194 i+=MPFR_SIGN_POS-MPFR_SIGN_NEG)
195 {
196 MPFR_SET_SIGN(x, i);
197 mpfr_add_z (x, x, z, (mpfr_rnd_t) r);
198 if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
199 {
200 printf("GMP Zero errors for add_z & rnd=%s & s=%d\n",
201 mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
202 mpfr_dump (x);
203 exit (1);
204 }
205 mpfr_sub_z (x, x, z, (mpfr_rnd_t) r);
206 if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
207 {
208 printf("GMP Zero errors for sub_z & rnd=%s & s=%d\n",
209 mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
210 mpfr_dump (x);
211 exit (1);
212 }
213 mpfr_mul_z (x, x, z, (mpfr_rnd_t) r);
214 if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
215 {
216 printf("GMP Zero errors for mul_z & rnd=%s & s=%d\n",
217 mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
218 mpfr_dump (x);
219 exit (1);
220 }
221 mpfr_add_q (x, x, q, (mpfr_rnd_t) r);
222 if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
223 {
224 printf("GMP Zero errors for add_q & rnd=%s & s=%d\n",
225 mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
226 mpfr_dump (x);
227 exit (1);
228 }
229 mpfr_sub_q (x, x, q, (mpfr_rnd_t) r);
230 if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
231 {
232 printf("GMP Zero errors for sub_q & rnd=%s & s=%d\n",
233 mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
234 mpfr_dump (x);
235 exit (1);
236 }
237 }
238 }
239
240 mpq_clear (q);
241 mpz_clear (z);
242 mpfr_clear (x);
243 }
244
245 static void
246 test_cmp_z (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
247 {
248 mpfr_t x, z;
249 mpz_t y;
250 mpfr_prec_t p;
251 int res1, res2;
252 int n;
253
254 mpfr_init (x);
255 mpfr_init2 (z, MPFR_PREC_MIN);
256 mpz_init (y);
257
258 /* check the erange flag when x is NaN */
259 mpfr_set_nan (x);
260 mpz_set_ui (y, 17);
261 mpfr_clear_erangeflag ();
262 res1 = mpfr_cmp_z (x, y);
263 if (res1 != 0 || mpfr_erangeflag_p () == 0)
264 {
265 printf ("Error for mpfr_cmp_z (NaN, 17)\n");
266 printf ("Return value: expected 0, got %d\n", res1);
267 printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
268 exit (1);
269 }
270
271 for(p=pmin ; p < pmax ; p++)
272 {
273 mpfr_set_prec (x, p);
274 for ( n = 0; n < nmax ; n++)
275 {
276 mpfr_urandomb (x, RANDS);
277 mpz_urandomb (y, RANDS, 1024);
278 if (!MPFR_IS_SINGULAR (x))
279 {
280 mpfr_sub_z (z, x, y, MPFR_RNDN);
281 res1 = (mpfr_sgn) (z);
282 res2 = mpfr_cmp_z (x, y);
283 if (res1 != res2)
284 {
285 printf("Error for mpfr_cmp_z: res=%d sub_z gives %d\n",
286 res2, res1);
287 exit (1);
288 }
289 }
290 }
291 }
292 mpz_clear (y);
293 mpfr_clear (x);
294 mpfr_clear (z);
295 }
296
297 static void
298 test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
299 {
300 mpfr_t x, z;
301 mpq_t y;
302 mpfr_prec_t p;
303 int res1, res2;
304 int n;
305
306 mpfr_init (x);
307 mpfr_init2 (z, MPFR_PREC_MIN);
308 mpq_init (y);
309
310 /* check the erange flag when x is NaN */
311 mpfr_set_nan (x);
312 mpq_set_ui (y, 17, 1);
313 mpfr_clear_erangeflag ();
314 res1 = mpfr_cmp_q (x, y);
315 if (res1 != 0 || mpfr_erangeflag_p () == 0)
316 {
317 printf ("Error for mpfr_cmp_q (NaN, 17)\n");
318 printf ("Return value: expected 0, got %d\n", res1);
319 printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
320 exit (1);
321 }
322
323 for(p=pmin ; p < pmax ; p++)
324 {
325 mpfr_set_prec (x, p);
326 for (n = 0 ; n < nmax ; n++)
327 {
328 mpfr_urandomb (x, RANDS);
329 mpq_set_ui (y, randlimb (), randlimb() );
330 if (!MPFR_IS_SINGULAR (x))
331 {
332 mpfr_sub_q (z, x, y, MPFR_RNDN);
333 res1 = (mpfr_sgn) (z);
334 res2 = mpfr_cmp_q (x, y);
335 if (res1 != res2)
336 {
337 printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n",
338 res2, res1);
339 exit (1);
340 }
341 }
342 }
343 }
344 mpq_clear (y);
345 mpfr_clear (x);
346 mpfr_clear (z);
347 }
348
349 static void
350 test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
351 {
352 mpfr_t x, z;
353 mpf_t y;
354 mpfr_prec_t p;
355 int res1, res2;
356 int n;
357
358 mpfr_init (x);
359 mpfr_init2 (z, pmax+GMP_NUMB_BITS);
360 mpf_init2 (y, MPFR_PREC_MIN);
361
362 /* check the erange flag when x is NaN */
363 mpfr_set_nan (x);
364 mpf_set_ui (y, 17);
365 mpfr_clear_erangeflag ();
366 res1 = mpfr_cmp_f (x, y);
367 if (res1 != 0 || mpfr_erangeflag_p () == 0)
368 {
369 printf ("Error for mpfr_cmp_f (NaN, 17)\n");
370 printf ("Return value: expected 0, got %d\n", res1);
371 printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
372 exit (1);
373 }
374
375 for(p=pmin ; p < pmax ; p+=3)
376 {
377 mpfr_set_prec (x, p);
378 mpf_set_prec (y, p);
379 for ( n = 0; n < nmax ; n++)
380 {
381 mpfr_urandomb (x, RANDS);
382 mpf_urandomb (y, RANDS, p);
383 if (!MPFR_IS_SINGULAR (x))
384 {
385 mpfr_set_f (z, y, MPFR_RNDN);
386 mpfr_sub (z, x, z, MPFR_RNDN);
387 res1 = (mpfr_sgn) (z);
388 res2 = mpfr_cmp_f (x, y);
389 if (res1 != res2)
390 {
391 printf("Error for mpfr_cmp_f: res=%d sub gives %d\n",
392 res2, res1);
393 exit (1);
394 }
395 }
396 }
397 }
398 mpf_clear (y);
399 mpfr_clear (x);
400 mpfr_clear (z);
401 }
402
403 static void
404 test_specialz (int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
405 void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
406 const char *op)
407 {
408 mpfr_t x1, x2;
409 mpz_t z1, z2;
410 int res;
411
412 mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
413 mpz_init (z1); mpz_init(z2);
414 mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
415 mpz_add_ui (z1, z1, 1);
416 mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
417 mpz_add_ui (z2, z2, 1);
418
419 res = mpfr_set_z(x1, z1, MPFR_RNDN);
420 if (res)
421 {
422 printf("Specialz %s: set_z1 error\n", op);
423 exit(1);
424 }
425 mpfr_set_z (x2, z2, MPFR_RNDN);
426 if (res)
427 {
428 printf("Specialz %s: set_z2 error\n", op);
429 exit(1);
430 }
431
432 /* (19!+1) * (20!+1) fits in a 128 bits number */
433 res = mpfr_func(x1, x1, z2, MPFR_RNDN);
434 if (res)
435 {
436 printf("Specialz %s: wrong inexact flag.\n", op);
437 exit(1);
438 }
439 mpz_func(z1, z1, z2);
440 res = mpfr_set_z (x2, z1, MPFR_RNDN);
441 if (res)
442 {
443 printf("Specialz %s: set_z2 error\n", op);
444 exit(1);
445 }
446 if (mpfr_cmp(x1, x2))
447 {
448 printf("Specialz %s: results differ.\nx1=", op);
449 mpfr_dump (x1);
450 printf ("x2=");
451 mpfr_dump (x2);
452 printf ("Z2=");
453 mpz_out_str (stdout, 2, z1);
454 putchar('\n');
455 exit(1);
456 }
457
458 mpz_set_ui (z1, 1);
459 mpz_set_ui (z2, 0);
460 mpfr_set_ui (x1, 1, MPFR_RNDN);
461 mpz_func (z1, z1, z2);
462 res = mpfr_func(x1, x1, z2, MPFR_RNDN);
463 mpfr_set_z (x2, z1, MPFR_RNDN);
464 if (mpfr_cmp(x1, x2))
465 {
466 printf("Specialz %s: results differ(2).\nx1=", op);
467 mpfr_dump (x1);
468 printf ("x2=");
469 mpfr_dump (x2);
470 exit(1);
471 }
472
473 mpz_clear (z1); mpz_clear(z2);
474 mpfr_clears (x1, x2, (mpfr_ptr) 0);
475 }
476
477 static void
478 test_special2z (int (*mpfr_func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t),
479 void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
480 const char *op)
481 {
482 mpfr_t x1, x2;
483 mpz_t z1, z2;
484 int res;
485
486 mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
487 mpz_init (z1); mpz_init(z2);
488 mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
489 mpz_add_ui (z1, z1, 1);
490 mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
491 mpz_add_ui (z2, z2, 1);
492
493 res = mpfr_set_z(x1, z1, MPFR_RNDN);
494 if (res)
495 {
496 printf("Special2z %s: set_z1 error\n", op);
497 exit(1);
498 }
499 mpfr_set_z (x2, z2, MPFR_RNDN);
500 if (res)
501 {
502 printf("Special2z %s: set_z2 error\n", op);
503 exit(1);
504 }
505
506 /* (19!+1) * (20!+1) fits in a 128 bits number */
507 res = mpfr_func(x1, z1, x2, MPFR_RNDN);
508 if (res)
509 {
510 printf("Special2z %s: wrong inexact flag.\n", op);
511 exit(1);
512 }
513 mpz_func(z1, z1, z2);
514 res = mpfr_set_z (x2, z1, MPFR_RNDN);
515 if (res)
516 {
517 printf("Special2z %s: set_z2 error\n", op);
518 exit(1);
519 }
520 if (mpfr_cmp(x1, x2))
521 {
522 printf("Special2z %s: results differ.\nx1=", op);
523 mpfr_dump (x1);
524 printf ("x2=");
525 mpfr_dump (x2);
526 printf ("Z2=");
527 mpz_out_str (stdout, 2, z1);
528 putchar('\n');
529 exit(1);
530 }
531
532 mpz_set_ui (z1, 0);
533 mpz_set_ui (z2, 1);
534 mpfr_set_ui (x2, 1, MPFR_RNDN);
535 res = mpfr_func(x1, z1, x2, MPFR_RNDN);
536 mpz_func (z1, z1, z2);
537 mpfr_set_z (x2, z1, MPFR_RNDN);
538 if (mpfr_cmp(x1, x2))
539 {
540 printf("Special2z %s: results differ(2).\nx1=", op);
541 mpfr_dump (x1);
542 printf ("x2=");
543 mpfr_dump (x2);
544 exit(1);
545 }
546
547 mpz_clear (z1); mpz_clear(z2);
548 mpfr_clears (x1, x2, (mpfr_ptr) 0);
549 }
550
551 static void
552 test_genericz (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
553 int (*func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
554 const char *op)
555 {
556 mpfr_prec_t prec;
557 mpfr_t arg1, dst_big, dst_small, tmp;
558 mpz_t arg2;
559 mpfr_rnd_t rnd;
560 int inexact, compare, compare2;
561 unsigned int n;
562
563 mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
564 mpz_init (arg2);
565
566 for (prec = p0; prec <= p1; prec++)
567 {
568 mpfr_set_prec (arg1, prec);
569 mpfr_set_prec (tmp, prec);
570 mpfr_set_prec (dst_small, prec);
571
572 for (n=0; n<N; n++)
573 {
574 mpfr_urandomb (arg1, RANDS);
575 mpz_urandomb (arg2, RANDS, 1024);
576 rnd = RND_RAND_NO_RNDF ();
577 mpfr_set_prec (dst_big, 2*prec);
578 compare = func (dst_big, arg1, arg2, rnd);
579 if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec))
580 {
581 mpfr_set (tmp, dst_big, rnd);
582 inexact = func (dst_small, arg1, arg2, rnd);
583 if (mpfr_cmp (tmp, dst_small))
584 {
585 printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n"
586 "arg1=",
587 (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
588 mpfr_dump (arg1);
589 printf ("arg2=");
590 mpz_out_str (stdout, 10, arg2);
591 printf ("\ngot ");
592 mpfr_dump (dst_small);
593 printf ("expected ");
594 mpfr_dump (tmp);
595 printf ("approx ");
596 mpfr_dump (dst_big);
597 exit (1);
598 }
599 compare2 = mpfr_cmp (tmp, dst_big);
600 /* if rounding to nearest, cannot know the sign of t - f(x)
601 because of composed rounding: y = o(f(x)) and t = o(y) */
602 if (compare * compare2 >= 0)
603 compare = compare + compare2;
604 else
605 compare = inexact; /* cannot determine sign(t-f(x)) */
606 if (((inexact == 0) && (compare != 0)) ||
607 ((inexact > 0) && (compare <= 0)) ||
608 ((inexact < 0) && (compare >= 0)))
609 {
610 printf ("Wrong inexact flag for rnd=%s and %s_z:\n"
611 "expected %d, got %d\n",
612 mpfr_print_rnd_mode (rnd), op, compare, inexact);
613 printf ("arg1="); mpfr_dump (arg1);
614 printf ("arg2="); mpz_out_str(stdout, 2, arg2);
615 printf ("\ndstl="); mpfr_dump (dst_big);
616 printf ("dsts="); mpfr_dump (dst_small);
617 printf ("tmp ="); mpfr_dump (tmp);
618 exit (1);
619 }
620 }
621 }
622 }
623
624 mpz_clear (arg2);
625 mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
626 }
627
628 static void
629 test_generic2z (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
630 int (*func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t),
631 const char *op)
632 {
633 mpfr_prec_t prec;
634 mpfr_t arg1, dst_big, dst_small, tmp;
635 mpz_t arg2;
636 mpfr_rnd_t rnd;
637 int inexact, compare, compare2;
638 unsigned int n;
639
640 mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
641 mpz_init (arg2);
642
643 for (prec = p0; prec <= p1; prec++)
644 {
645 mpfr_set_prec (arg1, prec);
646 mpfr_set_prec (tmp, prec);
647 mpfr_set_prec (dst_small, prec);
648
649 for (n=0; n<N; n++)
650 {
651 mpfr_urandomb (arg1, RANDS);
652 mpz_urandomb (arg2, RANDS, 1024);
653 rnd = RND_RAND_NO_RNDF ();
654 mpfr_set_prec (dst_big, 2*prec);
655 compare = func(dst_big, arg2, arg1, rnd);
656 if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec))
657 {
658 mpfr_set (tmp, dst_big, rnd);
659 inexact = func(dst_small, arg2, arg1, rnd);
660 if (mpfr_cmp (tmp, dst_small))
661 {
662 printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n"
663 "arg1=",
664 (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
665 mpfr_dump (arg1);
666 printf ("arg2=");
667 mpz_out_str (stdout, 10, arg2);
668 printf ("\ngot ");
669 mpfr_dump (dst_small);
670 printf ("expected ");
671 mpfr_dump (tmp);
672 printf ("approx ");
673 mpfr_dump (dst_big);
674 exit (1);
675 }
676 compare2 = mpfr_cmp (tmp, dst_big);
677 /* if rounding to nearest, cannot know the sign of t - f(x)
678 because of composed rounding: y = o(f(x)) and t = o(y) */
679 if (compare * compare2 >= 0)
680 compare = compare + compare2;
681 else
682 compare = inexact; /* cannot determine sign(t-f(x)) */
683 if (((inexact == 0) && (compare != 0)) ||
684 ((inexact > 0) && (compare <= 0)) ||
685 ((inexact < 0) && (compare >= 0)))
686 {
687 printf ("Wrong inexact flag for rnd=%s and %s_z:\n"
688 "expected %d, got %d\n",
689 mpfr_print_rnd_mode (rnd), op, compare, inexact);
690 printf ("arg1="); mpfr_dump (arg1);
691 printf ("arg2="); mpz_out_str(stdout, 2, arg2);
692 printf ("\ndstl="); mpfr_dump (dst_big);
693 printf ("dsts="); mpfr_dump (dst_small);
694 printf ("tmp ="); mpfr_dump (tmp);
695 exit (1);
696 }
697 }
698 }
699 }
700
701 mpz_clear (arg2);
702 mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
703 }
704
705 static void
706 test_genericq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
707 int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
708 const char *op)
709 {
710 mpfr_prec_t prec;
711 mpfr_t arg1, dst_big, dst_small, tmp;
712 mpq_t arg2;
713 mpfr_rnd_t rnd;
714 int inexact, compare, compare2;
715 unsigned int n;
716
717 mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
718 mpq_init (arg2);
719
720 for (prec = p0; prec <= p1; prec++)
721 {
722 mpfr_set_prec (arg1, prec);
723 mpfr_set_prec (tmp, prec);
724 mpfr_set_prec (dst_small, prec);
725
726 for (n=0; n<N; n++)
727 {
728 mpfr_urandomb (arg1, RANDS);
729 mpq_set_ui (arg2, randlimb (), randlimb() );
730 mpq_canonicalize (arg2);
731 rnd = RND_RAND_NO_RNDF ();
732 mpfr_set_prec (dst_big, prec+10);
733 compare = func(dst_big, arg1, arg2, rnd);
734 if (mpfr_can_round (dst_big, prec+10, rnd, rnd, prec))
735 {
736 mpfr_set (tmp, dst_big, rnd);
737 inexact = func(dst_small, arg1, arg2, rnd);
738 if (mpfr_cmp (tmp, dst_small))
739 {
740 printf ("Results differ for prec=%u rnd_mode=%s and %s_q:\n"
741 "arg1=",
742 (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
743 mpfr_dump (arg1);
744 printf ("arg2=");
745 mpq_out_str(stdout, 2, arg2);
746 printf ("\ngot ");
747 mpfr_dump (dst_small);
748 printf ("expected ");
749 mpfr_dump (tmp);
750 printf ("approx ");
751 mpfr_dump (dst_big);
752 exit (1);
753 }
754 compare2 = mpfr_cmp (tmp, dst_big);
755 /* if rounding to nearest, cannot know the sign of t - f(x)
756 because of composed rounding: y = o(f(x)) and t = o(y) */
757 if (compare * compare2 >= 0)
758 compare = compare + compare2;
759 else
760 compare = inexact; /* cannot determine sign(t-f(x)) */
761 if (((inexact == 0) && (compare != 0)) ||
762 ((inexact > 0) && (compare <= 0)) ||
763 ((inexact < 0) && (compare >= 0)))
764 {
765 printf ("Wrong inexact flag for rnd=%s and %s_q:\n"
766 "expected %d, got %d",
767 mpfr_print_rnd_mode (rnd), op, compare, inexact);
768 printf ("arg1="); mpfr_dump (arg1);
769 printf ("arg2="); mpq_out_str(stdout, 2, arg2);
770 printf ("\ndstl="); mpfr_dump (dst_big);
771 printf ("dsts="); mpfr_dump (dst_small);
772 printf ("tmp ="); mpfr_dump (tmp);
773 exit (1);
774 }
775 }
776 }
777 }
778
779 mpq_clear (arg2);
780 mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
781 }
782
783 static void
784 test_specialq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
785 int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
786 void (*mpq_func)(mpq_ptr, mpq_srcptr, mpq_srcptr),
787 const char *op)
788 {
789 mpfr_t fra, frb, frq;
790 mpq_t q1, q2, qr;
791 unsigned int n;
792 mpfr_prec_t prec;
793
794 for (prec = p0 ; prec < p1 ; prec++)
795 {
796 mpfr_inits2 (prec, fra, frb, frq, (mpfr_ptr) 0);
797 mpq_init (q1); mpq_init(q2); mpq_init (qr);
798
799 for( n = 0 ; n < N ; n++)
800 {
801 mpq_set_ui(q1, randlimb(), randlimb() );
802 mpq_set_ui(q2, randlimb(), randlimb() );
803 mpq_canonicalize (q1);
804 mpq_canonicalize (q2);
805 mpq_func (qr, q1, q2);
806 mpfr_set_q (fra, q1, MPFR_RNDD);
807 mpfr_func (fra, fra, q2, MPFR_RNDD);
808 mpfr_set_q (frb, q1, MPFR_RNDU);
809 mpfr_func (frb, frb, q2, MPFR_RNDU);
810 mpfr_set_q (frq, qr, MPFR_RNDN);
811 /* We should have fra <= qr <= frb */
812 if ( (mpfr_cmp(fra, frq) > 0) || (mpfr_cmp (frq, frb) > 0))
813 {
814 printf("Range error for prec=%lu and %s",
815 (unsigned long) prec, op);
816 printf ("\nq1="); mpq_out_str(stdout, 2, q1);
817 printf ("\nq2="); mpq_out_str(stdout, 2, q2);
818 printf ("\nfr_dn="); mpfr_dump (fra);
819 printf ("fr_q ="); mpfr_dump (frq);
820 printf ("fr_up="); mpfr_dump (frb);
821 exit (1);
822 }
823 }
824
825 mpq_clear (q1); mpq_clear (q2); mpq_clear (qr);
826 mpfr_clears (fra, frb, frq, (mpfr_ptr) 0);
827 }
828 }
829
830 static void
831 bug_mul_q_20100810 (void)
832 {
833 mpfr_t x;
834 mpfr_t y;
835 mpq_t q;
836 int inexact;
837
838 mpfr_init (x);
839 mpfr_init (y);
840 mpq_init (q);
841
842 /* mpfr_mul_q: the inexact value must be set in case of overflow */
843 mpq_set_ui (q, 4096, 3);
844 mpfr_set_inf (x, +1);
845 mpfr_nextbelow (x);
846 inexact = mpfr_mul_q (y, x, q, MPFR_RNDU);
847
848 if (inexact <= 0)
849 {
850 printf ("Overflow error in mpfr_mul_q. ");
851 printf ("Wrong inexact flag: got %d, should be positive.\n", inexact);
852
853 exit (1);
854 }
855 if (!mpfr_inf_p (y))
856 {
857 printf ("Overflow error in mpfr_mul_q (y, x, q, MPFR_RNDD). ");
858 printf ("\nx = ");
859 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
860 printf ("\nq = ");
861 mpq_out_str (stdout, 10, q);
862 printf ("\ny = ");
863 mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
864 printf (" (should be +infinity)\n");
865
866 exit (1);
867 }
868
869 mpq_clear (q);
870 mpfr_clear (y);
871 mpfr_clear (x);
872 }
873
874 static void
875 bug_div_q_20100810 (void)
876 {
877 mpfr_t x;
878 mpfr_t y;
879 mpq_t q;
880 int inexact;
881
882 mpfr_init (x);
883 mpfr_init (y);
884 mpq_init (q);
885
886 /* mpfr_div_q: the inexact value must be set in case of overflow */
887 mpq_set_ui (q, 3, 4096);
888 mpfr_set_inf (x, +1);
889 mpfr_nextbelow (x);
890 inexact = mpfr_div_q (y, x, q, MPFR_RNDU);
891
892 if (inexact <= 0)
893 {
894 printf ("Overflow error in mpfr_div_q. ");
895 printf ("Wrong inexact flag: got %d, should be positive.\n", inexact);
896
897 exit (1);
898 }
899 if (!mpfr_inf_p (y))
900 {
901 printf ("Overflow error in mpfr_div_q (y, x, q, MPFR_RNDD). ");
902 printf ("\nx = ");
903 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
904 printf ("\nq = ");
905 mpq_out_str (stdout, 10, q);
906 printf ("\ny = ");
907 mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
908 printf (" (should be +infinity)\n");
909
910 exit (1);
911 }
912
913 mpq_clear (q);
914 mpfr_clear (y);
915 mpfr_clear (x);
916 }
917
918 static void
919 bug_mul_div_q_20100818 (void)
920 {
921 mpq_t qa, qb;
922 mpfr_t x1, x2, y1, y2, y3;
923 mpfr_exp_t emin, emax, e;
924 int inex;
925 int rnd;
926
927 emin = mpfr_get_emin ();
928 emax = mpfr_get_emax ();
929 set_emin (MPFR_EMIN_MIN);
930 set_emax (MPFR_EMAX_MAX);
931
932 mpq_init (qa);
933 mpq_init (qb);
934 mpfr_inits2 (32, x1, x2, y1, y2, y3, (mpfr_ptr) 0);
935
936 mpq_set_ui (qa, 3, 17);
937 mpq_set_ui (qb, 17, 3);
938 inex = mpfr_set_ui (x1, 7, MPFR_RNDN);
939 MPFR_ASSERTN (inex == 0);
940
941 e = MPFR_EMAX_MAX - 3;
942 inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */
943 MPFR_ASSERTN (inex == 0);
944
945 RND_LOOP(rnd)
946 {
947 mpfr_mul_q (y1, x1, qa, (mpfr_rnd_t) rnd);
948 mpfr_div_q (y3, x1, qb, (mpfr_rnd_t) rnd);
949 MPFR_ASSERTN (mpfr_equal_p (y1, y3));
950 inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
951 MPFR_ASSERTN (inex == 0);
952 inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */
953 MPFR_ASSERTN (inex == 0);
954 mpfr_mul_q (y2, x2, qa, (mpfr_rnd_t) rnd);
955 if (! mpfr_equal_p (y2, y3))
956 {
957 printf ("Error 1 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
958 printf ("Expected "); mpfr_dump (y3);
959 printf ("Got "); mpfr_dump (y2);
960 exit (1);
961 }
962 mpfr_div_q (y2, x2, qb, (mpfr_rnd_t) rnd);
963 if (! mpfr_equal_p (y2, y3))
964 {
965 printf ("Error 2 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
966 printf ("Expected "); mpfr_dump (y3);
967 printf ("Got "); mpfr_dump (y2);
968 exit (1);
969 }
970 }
971
972 e = MPFR_EMIN_MIN;
973 inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN); /* x2 = x1 * 2^e */
974 MPFR_ASSERTN (inex == 0);
975
976 RND_LOOP(rnd)
977 {
978 mpfr_div_q (y1, x1, qa, (mpfr_rnd_t) rnd);
979 mpfr_mul_q (y3, x1, qb, (mpfr_rnd_t) rnd);
980 MPFR_ASSERTN (mpfr_equal_p (y1, y3));
981 inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
982 MPFR_ASSERTN (inex == 0);
983 inex = mpfr_mul (y3, y3, y1, MPFR_RNDN); /* y3 = y1 * 2^e */
984 MPFR_ASSERTN (inex == 0);
985 mpfr_div_q (y2, x2, qa, (mpfr_rnd_t) rnd);
986 if (! mpfr_equal_p (y2, y3))
987 {
988 printf ("Error 3 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
989 printf ("Expected "); mpfr_dump (y3);
990 printf ("Got "); mpfr_dump (y2);
991 exit (1);
992 }
993 mpfr_mul_q (y2, x2, qb, (mpfr_rnd_t) rnd);
994 if (! mpfr_equal_p (y2, y3))
995 {
996 printf ("Error 4 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
997 printf ("Expected "); mpfr_dump (y3);
998 printf ("Got "); mpfr_dump (y2);
999 exit (1);
1000 }
1001 }
1002
1003 mpq_clear (qa);
1004 mpq_clear (qb);
1005 mpfr_clears (x1, x2, y1, y2, y3, (mpfr_ptr) 0);
1006
1007 set_emin (emin);
1008 set_emax (emax);
1009 }
1010
1011 static void
1012 reduced_expo_range (void)
1013 {
1014 mpfr_t x;
1015 mpz_t z;
1016 mpq_t q;
1017 mpfr_exp_t emin;
1018 int inex;
1019
1020 emin = mpfr_get_emin ();
1021 set_emin (4);
1022
1023 mpfr_init2 (x, 32);
1024
1025 mpz_init (z);
1026 mpfr_clear_flags ();
1027 inex = mpfr_set_ui (x, 17, MPFR_RNDN);
1028 MPFR_ASSERTN (inex == 0);
1029 mpz_set_ui (z, 3);
1030 inex = mpfr_mul_z (x, x, z, MPFR_RNDN);
1031 if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 51) != 0)
1032 {
1033 printf ("Error 1 in reduce_expo_range: expected 51 with inex = 0,"
1034 " got\n");
1035 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1036 printf ("with inex = %d\n", inex);
1037 exit (1);
1038 }
1039 inex = mpfr_div_z (x, x, z, MPFR_RNDN);
1040 if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
1041 {
1042 printf ("Error 2 in reduce_expo_range: expected 17 with inex = 0,"
1043 " got\n");
1044 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1045 printf ("with inex = %d\n", inex);
1046 exit (1);
1047 }
1048 inex = mpfr_add_z (x, x, z, MPFR_RNDN);
1049 if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 20) != 0)
1050 {
1051 printf ("Error 3 in reduce_expo_range: expected 20 with inex = 0,"
1052 " got\n");
1053 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1054 printf ("with inex = %d\n", inex);
1055 exit (1);
1056 }
1057 inex = mpfr_sub_z (x, x, z, MPFR_RNDN);
1058 if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
1059 {
1060 printf ("Error 4 in reduce_expo_range: expected 17 with inex = 0,"
1061 " got\n");
1062 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1063 printf ("with inex = %d\n", inex);
1064 exit (1);
1065 }
1066 MPFR_ASSERTN (__gmpfr_flags == 0);
1067 if (mpfr_cmp_z (x, z) <= 0)
1068 {
1069 printf ("Error 5 in reduce_expo_range: expected a positive value.\n");
1070 exit (1);
1071 }
1072 mpz_clear (z);
1073
1074 mpq_init (q);
1075 mpq_set_ui (q, 1, 1);
1076 mpfr_set_ui (x, 16, MPFR_RNDN);
1077 inex = mpfr_add_q (x, x, q, MPFR_RNDN);
1078 if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
1079 {
1080 printf ("Error in reduce_expo_range for 16 + 1/1,"
1081 " got inex = %d and\nx = ", inex);
1082 mpfr_dump (x);
1083 exit (1);
1084 }
1085 inex = mpfr_sub_q (x, x, q, MPFR_RNDN);
1086 if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 16) != 0)
1087 {
1088 printf ("Error in reduce_expo_range for 17 - 1/1,"
1089 " got inex = %d and\nx = ", inex);
1090 mpfr_dump (x);
1091 exit (1);
1092 }
1093 mpq_clear (q);
1094
1095 mpfr_clear (x);
1096
1097 set_emin (emin);
1098 }
1099
1100 static void
1101 addsubq_overflow_aux (mpfr_exp_t e)
1102 {
1103 mpfr_t x, y;
1104 mpq_t q;
1105 mpfr_exp_t emax;
1106 int inex;
1107 int rnd;
1108 int sign, sub;
1109
1110 MPFR_ASSERTN (e <= LONG_MAX);
1111 emax = mpfr_get_emax ();
1112 set_emax (e);
1113 mpfr_inits2 (16, x, y, (mpfr_ptr) 0);
1114 mpq_init (q);
1115
1116 mpfr_set_inf (x, 1);
1117 mpfr_nextbelow (x);
1118 mpq_set_ui (q, 1, 1);
1119
1120 for (sign = 0; sign <= 1; sign++)
1121 {
1122 for (sub = 0; sub <= 1; sub++)
1123 {
1124 RND_LOOP(rnd)
1125 {
1126 unsigned int flags, ex_flags;
1127 int inf;
1128
1129 inf = rnd == MPFR_RNDA ||
1130 rnd == (sign ? MPFR_RNDD : MPFR_RNDU);
1131 ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0);
1132 mpfr_clear_flags ();
1133 inex = sub ?
1134 mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) :
1135 mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd);
1136 flags = __gmpfr_flags;
1137 if (inex == 0 || flags != ex_flags ||
1138 (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y)))
1139 {
1140 printf ("Error in addsubq_overflow_aux(%ld),"
1141 " sign = %d, %s\n", (long) e, sign,
1142 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
1143 printf ("Got inex = %d, y = ", inex);
1144 mpfr_dump (y);
1145 printf ("Expected flags:");
1146 flags_out (ex_flags);
1147 printf ("Got flags: ");
1148 flags_out (flags);
1149 exit (1);
1150 }
1151 }
1152 mpq_neg (q, q);
1153 }
1154 mpfr_neg (x, x, MPFR_RNDN);
1155 mpq_neg (q, q);
1156 }
1157
1158 mpq_clear (q);
1159 mpfr_clears (x, y, (mpfr_ptr) 0);
1160 set_emax (emax);
1161 }
1162
1163 static void
1164 addsubq_overflow (void)
1165 {
1166 addsubq_overflow_aux (4913);
1167 addsubq_overflow_aux (MPFR_EMAX_MAX);
1168 }
1169
1170 static void
1171 coverage_mpfr_mul_q_20110218 (void)
1172 {
1173 mpfr_t cmp, res, op1;
1174 mpq_t op2;
1175 int status;
1176
1177 mpfr_init2 (cmp, MPFR_PREC_MIN);
1178 mpfr_init2 (res, MPFR_PREC_MIN);
1179 mpfr_init_set_si (op1, 1, MPFR_RNDN);
1180
1181 mpq_init (op2);
1182 mpq_set_si (op2, 0, 0);
1183 mpz_set_si (mpq_denref (op2), 0);
1184
1185 status = mpfr_mul_q (res, op1, op2, MPFR_RNDN);
1186
1187 if ((status != 0) || (mpfr_cmp (cmp, res) != 0))
1188 {
1189 printf ("Results differ %d.\nres=", status);
1190 mpfr_dump (res);
1191 printf ("cmp=");
1192 mpfr_dump (cmp);
1193 exit (1);
1194 }
1195
1196 mpfr_set_si (op1, 1, MPFR_RNDN);
1197 mpq_set_si (op2, -1, 0);
1198
1199 status = mpfr_mul_q (res, op1, op2, MPFR_RNDN);
1200
1201 mpfr_set_inf (cmp, -1);
1202 if ((status != 0) || (mpfr_cmp(res, cmp) != 0))
1203 {
1204 printf ("mpfr_mul_q 1 * (-1/0) returned a wrong value:\n");
1205 printf (" expected ");
1206 mpfr_dump (cmp);
1207 printf (" got ");
1208 mpfr_dump (res);
1209 printf (" ternary value is %d\n", status);
1210 exit (1);
1211 }
1212
1213 mpq_clear (op2);
1214 mpfr_clear (op1);
1215 mpfr_clear (res);
1216 mpfr_clear (cmp);
1217 }
1218
1219 int
1220 main (int argc, char *argv[])
1221 {
1222 tests_start_mpfr ();
1223
1224 special ();
1225
1226 test_specialz (mpfr_add_z, mpz_add, "add");
1227 test_specialz (mpfr_sub_z, mpz_sub, "sub");
1228 test_specialz (mpfr_mul_z, mpz_mul, "mul");
1229 test_genericz (MPFR_PREC_MIN, 100, 100, mpfr_add_z, "add");
1230 test_genericz (MPFR_PREC_MIN, 100, 100, mpfr_sub_z, "sub");
1231 test_genericz (MPFR_PREC_MIN, 100, 100, mpfr_mul_z, "mul");
1232 test_genericz (MPFR_PREC_MIN, 100, 100, mpfr_div_z, "div");
1233 test_special2z (mpfr_z_sub, mpz_sub, "sub");
1234 test_generic2z (MPFR_PREC_MIN, 100, 100, mpfr_z_sub, "sub");
1235
1236 test_genericq (MPFR_PREC_MIN, 100, 100, mpfr_add_q, "add");
1237 test_genericq (MPFR_PREC_MIN, 100, 100, mpfr_sub_q, "sub");
1238 test_genericq (MPFR_PREC_MIN, 100, 100, mpfr_mul_q, "mul");
1239 test_genericq (MPFR_PREC_MIN, 100, 100, mpfr_div_q, "div");
1240 test_specialq (MPFR_PREC_MIN, 100, 100, mpfr_mul_q, mpq_mul, "mul");
1241 test_specialq (MPFR_PREC_MIN, 100, 100, mpfr_div_q, mpq_div, "div");
1242 test_specialq (MPFR_PREC_MIN, 100, 100, mpfr_add_q, mpq_add, "add");
1243 test_specialq (MPFR_PREC_MIN, 100, 100, mpfr_sub_q, mpq_sub, "sub");
1244
1245 test_cmp_z (MPFR_PREC_MIN, 100, 100);
1246 test_cmp_q (MPFR_PREC_MIN, 100, 100);
1247 test_cmp_f (MPFR_PREC_MIN, 100, 100);
1248
1249 check_for_zero ();
1250
1251 bug_mul_q_20100810 ();
1252 bug_div_q_20100810 ();
1253 bug_mul_div_q_20100818 ();
1254 reduced_expo_range ();
1255 addsubq_overflow ();
1256
1257 coverage_mpfr_mul_q_20110218 ();
1258
1259 tests_end_mpfr ();
1260 return 0;
1261 }
1262
1263 #else
1264
1265 int
1266 main (void)
1267 {
1268 return 77;
1269 }
1270
1271 #endif
1272