xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tgmpop.c (revision 49d8c9ecf4abd21261269266ef64939f71b3cd09)
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, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramel 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 <stdio.h>
25 #include <stdlib.h>
26 #include "mpfr-test.h"
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_dump (mpq_numref(q));                          \
35     printf ("   /"); mpz_dump (mpq_denref(q));                          \
36     exit (1);                                                           \
37   }
38 
39 #define CHECK_FORZ(str, cond)                                           \
40   if ((cond) == 0) {                                                    \
41     printf ("Special case error %s. Ternary value = %d, flags = %u\n",  \
42             str, res, __gmpfr_flags);                                   \
43     printf ("Got "); mpfr_dump (y);                                     \
44     printf ("X = "); mpfr_dump (x);                                     \
45     printf ("Z = "); mpz_dump (z);                                      \
46     exit (1);                                                           \
47   }
48 
49 static void
50 special (void)
51 {
52   mpfr_t x, y;
53   mpq_t q;
54   mpz_t z;
55   int res = 0;
56 
57   mpfr_init (x);
58   mpfr_init (y);
59   mpq_init (q);
60   mpz_init (z);
61 
62   /* cancellation in mpfr_add_q */
63   mpfr_set_prec (x, 60);
64   mpfr_set_prec (y, 20);
65   mpz_set_str (mpq_numref (q), "-187207494", 10);
66   mpz_set_str (mpq_denref (q), "5721", 10);
67   mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44");
68   mpfr_add_q (y, x, q, MPFR_RNDN);
69   CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0);
70 
71   mpfr_set_prec (x, 19);
72   mpfr_set_str_binary (x, "0.1011110101110011100E0");
73   mpz_set_str (mpq_numref (q), "187207494", 10);
74   mpz_set_str (mpq_denref (q), "5721", 10);
75   mpfr_set_prec (y, 29);
76   mpfr_add_q (y, x, q, MPFR_RNDD);
77   mpfr_set_prec (x, 29);
78   mpfr_set_str_binary (x, "11111111101001110011010001001E-14");
79   CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0);
80 
81   /* Inf */
82   mpfr_set_inf (x, 1);
83   mpz_set_str (mpq_numref (q), "395877315", 10);
84   mpz_set_str (mpq_denref (q), "3508975966", 10);
85   mpfr_set_prec (y, 118);
86   mpfr_add_q (y, x, q, MPFR_RNDU);
87   CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
88   mpfr_sub_q (y, x, q, MPFR_RNDU);
89   CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
90 
91   /* Nan */
92   MPFR_SET_NAN (x);
93   mpfr_add_q (y, x, q, MPFR_RNDU);
94   CHECK_FOR ("nan", mpfr_nan_p (y));
95   mpfr_sub_q (y, x, q, MPFR_RNDU);
96   CHECK_FOR ("nan", mpfr_nan_p (y));
97 
98   /* Exact value */
99   mpfr_set_prec (x, 60);
100   mpfr_set_prec (y, 60);
101   mpfr_set_str1 (x, "0.5");
102   mpz_set_str (mpq_numref (q), "3", 10);
103   mpz_set_str (mpq_denref (q), "2", 10);
104   res = mpfr_add_q (y, x, q, MPFR_RNDU);
105   CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0);
106   res = mpfr_sub_q (y, x, q, MPFR_RNDU);
107   CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0);
108 
109   /* Inf Rationnal */
110   mpq_set_ui (q, 1, 0);
111   mpfr_set_str1 (x, "0.5");
112   res = mpfr_add_q (y, x, q, MPFR_RNDN);
113   CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
114   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
115   CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
116   mpq_set_si (q, -1, 0);
117   res = mpfr_add_q (y, x, q, MPFR_RNDN);
118   CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
119   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
120   CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
121   res = mpfr_div_q (y, x, q, MPFR_RNDN);
122   CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_SIGN (y) < 0 && res == 0);
123   mpq_set_ui (q, 1, 0);
124   mpfr_set_inf (x, 1);
125   res = mpfr_add_q (y, x, q, MPFR_RNDN);
126   CHECK_FOR ("+Inf + +Inf", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
127   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
128   CHECK_FOR ("+Inf - +Inf", MPFR_IS_NAN (y) && res == 0);
129   mpfr_set_inf (x, -1);
130   res = mpfr_add_q (y, x, q, MPFR_RNDN);
131   CHECK_FOR ("-Inf + +Inf", MPFR_IS_NAN (y) && res == 0);
132   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
133   CHECK_FOR ("-Inf - +Inf", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
134   mpq_set_si (q, -1, 0);
135   mpfr_set_inf (x, 1);
136   res = mpfr_add_q (y, x, q, MPFR_RNDN);
137   CHECK_FOR ("+Inf + -Inf", MPFR_IS_NAN (y) && res == 0);
138   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
139   CHECK_FOR ("+Inf - -Inf", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
140   mpfr_set_inf (x, -1);
141   res = mpfr_add_q (y, x, q, MPFR_RNDN);
142   CHECK_FOR ("-Inf + -Inf", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
143   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
144   CHECK_FOR ("-Inf - -Inf", MPFR_IS_NAN (y) && res == 0);
145 
146   /* 0 */
147   mpq_set_ui (q, 0, 1);
148   mpfr_set_ui (x, 42, MPFR_RNDN);
149   res = mpfr_add_q (y, x, q, MPFR_RNDN);
150   CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
151   res = mpfr_sub_q (y, x, q, MPFR_RNDN);
152   CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
153   res = mpfr_mul_q (y, x, q, MPFR_RNDN);
154   CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_SIGN (y) > 0 && res == 0);
155   mpfr_clear_flags ();
156   res = mpfr_div_q (y, x, q, MPFR_RNDN);
157   CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0
158              && mpfr_divby0_p ());
159   mpz_set_ui (z, 0);
160   mpfr_clear_flags ();
161   res = mpfr_div_z (y, x, z, MPFR_RNDN);
162   CHECK_FORZ ("42/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0
163               && mpfr_divby0_p ());
164 
165   mpz_clear (z);
166   mpq_clear (q);
167   mpfr_clear (x);
168   mpfr_clear (y);
169 }
170 
171 static void
172 check_for_zero (void)
173 {
174   /* Check that 0 is unsigned! */
175   mpq_t q;
176   mpz_t z;
177   mpfr_t x;
178   int r;
179   mpfr_sign_t i;
180 
181   mpfr_init (x);
182   mpz_init (z);
183   mpq_init (q);
184 
185   mpz_set_ui (z, 0);
186   mpq_set_ui (q, 0, 1);
187 
188   MPFR_SET_ZERO (x);
189   RND_LOOP (r)
190     {
191       for (i = MPFR_SIGN_NEG ; i <= MPFR_SIGN_POS ;
192            i+=MPFR_SIGN_POS-MPFR_SIGN_NEG)
193         {
194           MPFR_SET_SIGN(x, i);
195           mpfr_add_z (x, x, z, (mpfr_rnd_t) r);
196           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
197             {
198               printf("GMP Zero errors for add_z & rnd=%s & s=%d\n",
199                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
200               mpfr_dump (x);
201               exit (1);
202             }
203           mpfr_sub_z (x, x, z, (mpfr_rnd_t) r);
204           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
205             {
206               printf("GMP Zero errors for sub_z & rnd=%s & s=%d\n",
207                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
208               mpfr_dump (x);
209               exit (1);
210             }
211           mpfr_mul_z (x, x, z, (mpfr_rnd_t) r);
212           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
213             {
214               printf("GMP Zero errors for mul_z & rnd=%s & s=%d\n",
215                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
216               mpfr_dump (x);
217               exit (1);
218             }
219           mpfr_add_q (x, x, q, (mpfr_rnd_t) r);
220           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
221             {
222               printf("GMP Zero errors for add_q & rnd=%s & s=%d\n",
223                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
224               mpfr_dump (x);
225               exit (1);
226             }
227           mpfr_sub_q (x, x, q, (mpfr_rnd_t) r);
228           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
229             {
230               printf("GMP Zero errors for sub_q & rnd=%s & s=%d\n",
231                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
232               mpfr_dump (x);
233               exit (1);
234              }
235         }
236     }
237 
238   mpq_clear (q);
239   mpz_clear (z);
240   mpfr_clear (x);
241 }
242 
243 static void
244 test_cmp_z (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
245 {
246   mpfr_t x, z;
247   mpz_t  y;
248   mpfr_prec_t p;
249   int res1, res2;
250   int n;
251 
252   mpfr_init (x);
253   mpfr_init2 (z, MPFR_PREC_MIN);
254   mpz_init (y);
255 
256   /* check the erange flag when x is NaN */
257   mpfr_set_nan (x);
258   mpz_set_ui (y, 17);
259   mpfr_clear_erangeflag ();
260   res1 = mpfr_cmp_z (x, y);
261   if (res1 != 0 || mpfr_erangeflag_p () == 0)
262     {
263       printf ("Error for mpfr_cmp_z (NaN, 17)\n");
264       printf ("Return value: expected 0, got %d\n", res1);
265       printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
266       exit (1);
267     }
268 
269   for(p=pmin ; p < pmax ; p++)
270     {
271       mpfr_set_prec (x, p);
272       for ( n = 0; n < nmax ; n++)
273         {
274           mpfr_urandomb (x, RANDS);
275           mpz_urandomb  (y, RANDS, 1024);
276           if (!MPFR_IS_SINGULAR (x))
277             {
278               mpfr_sub_z (z, x, y, MPFR_RNDN);
279               res1 = mpfr_sgn (z);
280               res2 = mpfr_cmp_z (x, y);
281               if (res1 != res2)
282                 {
283                   printf("Error for mpfr_cmp_z: res=%d sub_z gives %d\n",
284                          res2, res1);
285                   exit (1);
286                 }
287             }
288         }
289     }
290   mpz_clear (y);
291   mpfr_clear (x);
292   mpfr_clear (z);
293 }
294 
295 static void
296 test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
297 {
298   mpfr_t x, z;
299   mpq_t  y;
300   mpfr_prec_t p;
301   int res1, res2;
302   int n;
303 
304   mpfr_init (x);
305   mpfr_init2 (z, MPFR_PREC_MIN);
306   mpq_init (y);
307 
308   /* check the erange flag when x is NaN */
309   mpfr_set_nan (x);
310   mpq_set_ui (y, 17, 1);
311   mpfr_clear_erangeflag ();
312   res1 = mpfr_cmp_q (x, y);
313   if (res1 != 0 || mpfr_erangeflag_p () == 0)
314     {
315       printf ("Error for mpfr_cmp_q (NaN, 17)\n");
316       printf ("Return value: expected 0, got %d\n", res1);
317       printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
318       exit (1);
319     }
320 
321   for(p=pmin ; p < pmax ; p++)
322     {
323       mpfr_set_prec (x, p);
324       for (n = 0 ; n < nmax ; n++)
325         {
326           mpfr_urandomb (x, RANDS);
327           mpq_set_ui (y, randlimb (), randlimb() );
328           if (!MPFR_IS_SINGULAR (x))
329             {
330               mpfr_sub_q (z, x, y, MPFR_RNDN);
331               res1 = mpfr_sgn (z);
332               res2 = mpfr_cmp_q (x, y);
333               if (res1 != res2)
334                 {
335                   printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n",
336                          res2, res1);
337                   exit (1);
338                 }
339             }
340         }
341     }
342   mpq_clear (y);
343   mpfr_clear (x);
344   mpfr_clear (z);
345 }
346 
347 static void
348 test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
349 {
350   mpfr_t x, z;
351   mpf_t  y;
352   mpfr_prec_t p;
353   int res1, res2;
354   int n;
355 
356   mpfr_init (x);
357   mpfr_init2 (z, pmax+GMP_NUMB_BITS);
358   mpf_init2 (y, MPFR_PREC_MIN);
359 
360   /* check the erange flag when x is NaN */
361   mpfr_set_nan (x);
362   mpf_set_ui (y, 17);
363   mpfr_clear_erangeflag ();
364   res1 = mpfr_cmp_f (x, y);
365   if (res1 != 0 || mpfr_erangeflag_p () == 0)
366     {
367       printf ("Error for mpfr_cmp_f (NaN, 17)\n");
368       printf ("Return value: expected 0, got %d\n", res1);
369       printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
370       exit (1);
371     }
372 
373   for(p=pmin ; p < pmax ; p+=3)
374     {
375       mpfr_set_prec (x, p);
376       mpf_set_prec (y, p);
377       for ( n = 0; n < nmax ; n++)
378         {
379           mpfr_urandomb (x, RANDS);
380           mpf_urandomb  (y, RANDS, p);
381           if (!MPFR_IS_SINGULAR (x))
382             {
383               mpfr_set_f (z, y, MPFR_RNDN);
384               mpfr_sub   (z, x, z, MPFR_RNDN);
385               res1 = mpfr_sgn (z);
386               res2 = mpfr_cmp_f (x, y);
387               if (res1 != res2)
388                 {
389                   printf("Error for mpfr_cmp_f: res=%d sub gives %d\n",
390                          res2, res1);
391                   exit (1);
392                 }
393             }
394         }
395     }
396   mpf_clear (y);
397   mpfr_clear (x);
398   mpfr_clear (z);
399 }
400 
401 static void
402 test_specialz (int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
403                void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
404                const char *op)
405 {
406   mpfr_t x1, x2;
407   mpz_t  z1, z2;
408   int res;
409 
410   mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
411   mpz_init (z1); mpz_init(z2);
412   mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
413   mpz_add_ui (z1, z1, 1);
414   mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
415   mpz_add_ui (z2, z2, 1);
416 
417   res = mpfr_set_z(x1, z1, MPFR_RNDN);
418   if (res)
419     {
420       printf("Specialz %s: set_z1 error\n", op);
421       exit(1);
422     }
423   mpfr_set_z (x2, z2, MPFR_RNDN);
424   if (res)
425     {
426       printf("Specialz %s: set_z2 error\n", op);
427       exit(1);
428     }
429 
430   /* (19!+1) * (20!+1) fits in a 128 bits number */
431   res = mpfr_func(x1, x1, z2, MPFR_RNDN);
432   if (res)
433     {
434       printf("Specialz %s: wrong inexact flag.\n", op);
435       exit(1);
436     }
437   mpz_func(z1, z1, z2);
438   res = mpfr_set_z (x2, z1, MPFR_RNDN);
439   if (res)
440     {
441       printf("Specialz %s: set_z2 error\n", op);
442       exit(1);
443     }
444   if (mpfr_cmp(x1, x2))
445     {
446       printf("Specialz %s: results differ.\nx1=", op);
447       mpfr_print_binary(x1);
448       printf("\nx2=");
449       mpfr_print_binary(x2);
450       printf ("\nZ2=");
451       mpz_out_str (stdout, 2, z1);
452       putchar('\n');
453       exit(1);
454     }
455 
456   mpz_set_ui (z1, 1);
457   mpz_set_ui (z2, 0);
458   mpfr_set_ui (x1, 1, MPFR_RNDN);
459   mpz_func (z1, z1, z2);
460   res = mpfr_func(x1, x1, z2, MPFR_RNDN);
461   mpfr_set_z (x2, z1, MPFR_RNDN);
462   if (mpfr_cmp(x1, x2))
463     {
464       printf("Specialz %s: results differ(2).\nx1=", op);
465       mpfr_print_binary(x1);
466       printf("\nx2=");
467       mpfr_print_binary(x2);
468       putchar('\n');
469       exit(1);
470     }
471 
472   mpz_clear (z1); mpz_clear(z2);
473   mpfr_clears (x1, x2, (mpfr_ptr) 0);
474 }
475 
476 static void
477 test_special2z (int (*mpfr_func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t),
478                void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
479                const char *op)
480 {
481   mpfr_t x1, x2;
482   mpz_t  z1, z2;
483   int res;
484 
485   mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
486   mpz_init (z1); mpz_init(z2);
487   mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
488   mpz_add_ui (z1, z1, 1);
489   mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
490   mpz_add_ui (z2, z2, 1);
491 
492   res = mpfr_set_z(x1, z1, MPFR_RNDN);
493   if (res)
494     {
495       printf("Special2z %s: set_z1 error\n", op);
496       exit(1);
497     }
498   mpfr_set_z (x2, z2, MPFR_RNDN);
499   if (res)
500     {
501       printf("Special2z %s: set_z2 error\n", op);
502       exit(1);
503     }
504 
505   /* (19!+1) * (20!+1) fits in a 128 bits number */
506   res = mpfr_func(x1, z1, x2, MPFR_RNDN);
507   if (res)
508     {
509       printf("Special2z %s: wrong inexact flag.\n", op);
510       exit(1);
511     }
512   mpz_func(z1, z1, z2);
513   res = mpfr_set_z (x2, z1, MPFR_RNDN);
514   if (res)
515     {
516       printf("Special2z %s: set_z2 error\n", op);
517       exit(1);
518     }
519   if (mpfr_cmp(x1, x2))
520     {
521       printf("Special2z %s: results differ.\nx1=", op);
522       mpfr_print_binary(x1);
523       printf("\nx2=");
524       mpfr_print_binary(x2);
525       printf ("\nZ2=");
526       mpz_out_str (stdout, 2, z1);
527       putchar('\n');
528       exit(1);
529     }
530 
531   mpz_set_ui (z1, 0);
532   mpz_set_ui (z2, 1);
533   mpfr_set_ui (x2, 1, MPFR_RNDN);
534   res = mpfr_func(x1, z1, x2, MPFR_RNDN);
535   mpz_func (z1, z1, z2);
536   mpfr_set_z (x2, z1, MPFR_RNDN);
537   if (mpfr_cmp(x1, x2))
538     {
539       printf("Special2z %s: results differ(2).\nx1=", op);
540       mpfr_print_binary(x1);
541       printf("\nx2=");
542       mpfr_print_binary(x2);
543       putchar('\n');
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 ();
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_print_binary (arg1);
589                   printf("\narg2=");
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 ("\narg1="); mpfr_print_binary (arg1);
614                   printf ("\narg2="); mpz_out_str(stdout, 2, arg2);
615                   printf ("\ndstl="); mpfr_print_binary (dst_big);
616                   printf ("\ndsts="); mpfr_print_binary (dst_small);
617                   printf ("\ntmp ="); 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 ();
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_print_binary (arg1);
666                   printf("\narg2=");
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 ("\narg1="); mpfr_print_binary (arg1);
691                   printf ("\narg2="); mpz_out_str(stdout, 2, arg2);
692                   printf ("\ndstl="); mpfr_print_binary (dst_big);
693                   printf ("\ndsts="); mpfr_print_binary (dst_small);
694                   printf ("\ntmp ="); 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 ();
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_print_binary (arg1);
744                   printf("\narg2=");
745                   mpq_out_str(stdout, 2, arg2);
746                   printf ("\ngot      ");
747                   mpfr_print_binary (dst_small);
748                   printf ("\nexpected ");
749                   mpfr_print_binary (tmp);
750                   printf ("\napprox  ");
751                   mpfr_print_binary (dst_big);
752                   putchar('\n');
753                   exit (1);
754                 }
755               compare2 = mpfr_cmp (tmp, dst_big);
756               /* if rounding to nearest, cannot know the sign of t - f(x)
757                  because of composed rounding: y = o(f(x)) and t = o(y) */
758               if (compare * compare2 >= 0)
759                 compare = compare + compare2;
760               else
761                 compare = inexact; /* cannot determine sign(t-f(x)) */
762               if (((inexact == 0) && (compare != 0)) ||
763                   ((inexact > 0) && (compare <= 0)) ||
764                   ((inexact < 0) && (compare >= 0)))
765                 {
766                   printf ("Wrong inexact flag for rnd=%s and %s_q:\n"
767                           "expected %d, got %d",
768                           mpfr_print_rnd_mode (rnd), op, compare, inexact);
769                   printf ("\narg1="); mpfr_print_binary (arg1);
770                   printf ("\narg2="); mpq_out_str(stdout, 2, arg2);
771                   printf ("\ndstl="); mpfr_print_binary (dst_big);
772                   printf ("\ndsts="); mpfr_print_binary (dst_small);
773                   printf ("\ntmp ="); mpfr_print_binary (tmp);
774                   putchar('\n');
775                   exit (1);
776                 }
777             }
778         }
779     }
780 
781   mpq_clear (arg2);
782   mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
783 }
784 
785 static void
786 test_specialq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
787                int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
788                void (*mpq_func)(mpq_ptr, mpq_srcptr, mpq_srcptr),
789                const char *op)
790 {
791   mpfr_t fra, frb, frq;
792   mpq_t  q1, q2, qr;
793   unsigned int n;
794   mpfr_prec_t prec;
795 
796   for (prec = p0 ; prec < p1 ; prec++)
797     {
798       mpfr_inits2 (prec, fra, frb, frq, (mpfr_ptr) 0);
799       mpq_init (q1); mpq_init(q2); mpq_init (qr);
800 
801       for( n = 0 ; n < N ; n++)
802         {
803           mpq_set_ui(q1, randlimb(), randlimb() );
804           mpq_set_ui(q2, randlimb(), randlimb() );
805           mpq_canonicalize (q1);
806           mpq_canonicalize (q2);
807           mpq_func (qr, q1, q2);
808           mpfr_set_q (fra, q1, MPFR_RNDD);
809           mpfr_func (fra, fra, q2, MPFR_RNDD);
810           mpfr_set_q (frb, q1, MPFR_RNDU);
811           mpfr_func (frb, frb, q2, MPFR_RNDU);
812           mpfr_set_q (frq, qr, MPFR_RNDN);
813           /* We should have fra <= qr <= frb */
814           if ( (mpfr_cmp(fra, frq) > 0) || (mpfr_cmp (frq, frb) > 0))
815             {
816               printf("Range error for prec=%lu and %s",
817                      (unsigned long) prec, op);
818               printf ("\nq1="); mpq_out_str(stdout, 2, q1);
819               printf ("\nq2="); mpq_out_str(stdout, 2, q2);
820               printf ("\nfr_dn="); mpfr_print_binary (fra);
821               printf ("\nfr_q ="); mpfr_print_binary (frq);
822               printf ("\nfr_up="); mpfr_print_binary (frb);
823               putchar('\n');
824               exit (1);
825             }
826         }
827 
828       mpq_clear (q1); mpq_clear (q2); mpq_clear (qr);
829       mpfr_clears (fra, frb, frq, (mpfr_ptr) 0);
830     }
831 }
832 
833 static void
834 bug_mul_q_20100810 (void)
835 {
836   mpfr_t x;
837   mpfr_t y;
838   mpq_t q;
839   int inexact;
840 
841   mpfr_init (x);
842   mpfr_init (y);
843   mpq_init (q);
844 
845   /* mpfr_mul_q: the inexact value must be set in case of overflow */
846   mpq_set_ui (q, 4096, 3);
847   mpfr_set_inf (x, +1);
848   mpfr_nextbelow (x);
849   inexact = mpfr_mul_q (y, x, q, MPFR_RNDU);
850 
851   if (inexact <= 0)
852     {
853       printf ("Overflow error in mpfr_mul_q. ");
854       printf ("Wrong inexact flag: got %d, should be positive.\n", inexact);
855 
856       exit (1);
857     }
858   if (!mpfr_inf_p (y))
859     {
860       printf ("Overflow error in mpfr_mul_q (y, x, q, MPFR_RNDD). ");
861       printf ("\nx = ");
862       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
863       printf ("\nq = ");
864       mpq_out_str (stdout, 10, q);
865       printf ("\ny = ");
866       mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
867       printf (" (should be +infinity)\n");
868 
869       exit (1);
870     }
871 
872   mpq_clear (q);
873   mpfr_clear (y);
874   mpfr_clear (x);
875 }
876 
877 static void
878 bug_div_q_20100810 (void)
879 {
880   mpfr_t x;
881   mpfr_t y;
882   mpq_t q;
883   int inexact;
884 
885   mpfr_init (x);
886   mpfr_init (y);
887   mpq_init (q);
888 
889   /* mpfr_div_q: the inexact value must be set in case of overflow */
890   mpq_set_ui (q, 3, 4096);
891   mpfr_set_inf (x, +1);
892   mpfr_nextbelow (x);
893   inexact = mpfr_div_q (y, x, q, MPFR_RNDU);
894 
895   if (inexact <= 0)
896     {
897       printf ("Overflow error in mpfr_div_q. ");
898       printf ("Wrong inexact flag: got %d, should be positive.\n", inexact);
899 
900       exit (1);
901     }
902   if (!mpfr_inf_p (y))
903     {
904       printf ("Overflow error in mpfr_div_q (y, x, q, MPFR_RNDD). ");
905       printf ("\nx = ");
906       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDD);
907       printf ("\nq = ");
908       mpq_out_str (stdout, 10, q);
909       printf ("\ny = ");
910       mpfr_out_str (stdout, 10, 0, y, MPFR_RNDD);
911       printf (" (should be +infinity)\n");
912 
913       exit (1);
914     }
915 
916   mpq_clear (q);
917   mpfr_clear (y);
918   mpfr_clear (x);
919 }
920 
921 static void
922 bug_mul_div_q_20100818 (void)
923 {
924   mpq_t qa, qb;
925   mpfr_t x1, x2, y1, y2, y3;
926   mpfr_exp_t emin, emax, e;
927   int inex;
928   int rnd;
929 
930   emin = mpfr_get_emin ();
931   emax = mpfr_get_emax ();
932   set_emin (MPFR_EMIN_MIN);
933   set_emax (MPFR_EMAX_MAX);
934 
935   mpq_init (qa);
936   mpq_init (qb);
937   mpfr_inits2 (32, x1, x2, y1, y2, y3, (mpfr_ptr) 0);
938 
939   mpq_set_ui (qa, 3, 17);
940   mpq_set_ui (qb, 17, 3);
941   inex = mpfr_set_ui (x1, 7, MPFR_RNDN);
942   MPFR_ASSERTN (inex == 0);
943 
944   e = MPFR_EMAX_MAX - 3;
945   inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN);  /* x2 = x1 * 2^e */
946   MPFR_ASSERTN (inex == 0);
947 
948   RND_LOOP(rnd)
949     {
950       mpfr_mul_q (y1, x1, qa, (mpfr_rnd_t) rnd);
951       mpfr_div_q (y3, x1, qb, (mpfr_rnd_t) rnd);
952       MPFR_ASSERTN (mpfr_equal_p (y1, y3));
953       inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
954       MPFR_ASSERTN (inex == 0);
955       inex = mpfr_mul (y3, y3, y1, MPFR_RNDN);  /* y3 = y1 * 2^e */
956       MPFR_ASSERTN (inex == 0);
957       mpfr_mul_q (y2, x2, qa, (mpfr_rnd_t) rnd);
958       if (! mpfr_equal_p (y2, y3))
959         {
960           printf ("Error 1 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
961           printf ("Expected "); mpfr_dump (y3);
962           printf ("Got      "); mpfr_dump (y2);
963           exit (1);
964         }
965       mpfr_div_q (y2, x2, qb, (mpfr_rnd_t) rnd);
966       if (! mpfr_equal_p (y2, y3))
967         {
968           printf ("Error 2 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
969           printf ("Expected "); mpfr_dump (y3);
970           printf ("Got      "); mpfr_dump (y2);
971           exit (1);
972         }
973     }
974 
975   e = MPFR_EMIN_MIN;
976   inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN);  /* x2 = x1 * 2^e */
977   MPFR_ASSERTN (inex == 0);
978 
979   RND_LOOP(rnd)
980     {
981       mpfr_div_q (y1, x1, qa, (mpfr_rnd_t) rnd);
982       mpfr_mul_q (y3, x1, qb, (mpfr_rnd_t) rnd);
983       MPFR_ASSERTN (mpfr_equal_p (y1, y3));
984       inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
985       MPFR_ASSERTN (inex == 0);
986       inex = mpfr_mul (y3, y3, y1, MPFR_RNDN);  /* y3 = y1 * 2^e */
987       MPFR_ASSERTN (inex == 0);
988       mpfr_div_q (y2, x2, qa, (mpfr_rnd_t) rnd);
989       if (! mpfr_equal_p (y2, y3))
990         {
991           printf ("Error 3 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
992           printf ("Expected "); mpfr_dump (y3);
993           printf ("Got      "); mpfr_dump (y2);
994           exit (1);
995         }
996       mpfr_mul_q (y2, x2, qb, (mpfr_rnd_t) rnd);
997       if (! mpfr_equal_p (y2, y3))
998         {
999           printf ("Error 4 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
1000           printf ("Expected "); mpfr_dump (y3);
1001           printf ("Got      "); mpfr_dump (y2);
1002           exit (1);
1003         }
1004     }
1005 
1006   mpq_clear (qa);
1007   mpq_clear (qb);
1008   mpfr_clears (x1, x2, y1, y2, y3, (mpfr_ptr) 0);
1009 
1010   set_emin (emin);
1011   set_emax (emax);
1012 }
1013 
1014 static void
1015 reduced_expo_range (void)
1016 {
1017   mpfr_t x;
1018   mpz_t z;
1019   mpq_t q;
1020   mpfr_exp_t emin;
1021   int inex;
1022 
1023   emin = mpfr_get_emin ();
1024   set_emin (4);
1025 
1026   mpfr_init2 (x, 32);
1027 
1028   mpz_init (z);
1029   mpfr_clear_flags ();
1030   inex = mpfr_set_ui (x, 17, MPFR_RNDN);
1031   MPFR_ASSERTN (inex == 0);
1032   mpz_set_ui (z, 3);
1033   inex = mpfr_mul_z (x, x, z, MPFR_RNDN);
1034   if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 51) != 0)
1035     {
1036       printf ("Error 1 in reduce_expo_range: expected 51 with inex = 0,"
1037               " got\n");
1038       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1039       printf ("with inex = %d\n", inex);
1040       exit (1);
1041     }
1042   inex = mpfr_div_z (x, x, z, MPFR_RNDN);
1043   if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
1044     {
1045       printf ("Error 2 in reduce_expo_range: expected 17 with inex = 0,"
1046               " got\n");
1047       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1048       printf ("with inex = %d\n", inex);
1049       exit (1);
1050     }
1051   inex = mpfr_add_z (x, x, z, MPFR_RNDN);
1052   if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 20) != 0)
1053     {
1054       printf ("Error 3 in reduce_expo_range: expected 20 with inex = 0,"
1055               " got\n");
1056       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1057       printf ("with inex = %d\n", inex);
1058       exit (1);
1059     }
1060   inex = mpfr_sub_z (x, x, z, MPFR_RNDN);
1061   if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
1062     {
1063       printf ("Error 4 in reduce_expo_range: expected 17 with inex = 0,"
1064               " got\n");
1065       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
1066       printf ("with inex = %d\n", inex);
1067       exit (1);
1068     }
1069   MPFR_ASSERTN (__gmpfr_flags == 0);
1070   if (mpfr_cmp_z (x, z) <= 0)
1071     {
1072       printf ("Error 5 in reduce_expo_range: expected a positive value.\n");
1073       exit (1);
1074     }
1075   mpz_clear (z);
1076 
1077   mpq_init (q);
1078   mpq_set_ui (q, 1, 1);
1079   mpfr_set_ui (x, 16, MPFR_RNDN);
1080   inex = mpfr_add_q (x, x, q, MPFR_RNDN);
1081   if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 17) != 0)
1082     {
1083       printf ("Error in reduce_expo_range for 16 + 1/1,"
1084               " got inex = %d and\nx = ", inex);
1085       mpfr_dump (x);
1086       exit (1);
1087     }
1088   inex = mpfr_sub_q (x, x, q, MPFR_RNDN);
1089   if (inex != 0 || MPFR_IS_NAN (x) || mpfr_cmp_ui (x, 16) != 0)
1090     {
1091       printf ("Error in reduce_expo_range for 17 - 1/1,"
1092               " got inex = %d and\nx = ", inex);
1093       mpfr_dump (x);
1094       exit (1);
1095     }
1096   mpq_clear (q);
1097 
1098   mpfr_clear (x);
1099 
1100   set_emin (emin);
1101 }
1102 
1103 static void
1104 addsubq_overflow_aux (mpfr_exp_t e)
1105 {
1106   mpfr_t x, y;
1107   mpq_t q;
1108   mpfr_exp_t emax;
1109   int inex;
1110   int rnd;
1111   int sign, sub;
1112 
1113   MPFR_ASSERTN (e <= LONG_MAX);
1114   emax = mpfr_get_emax ();
1115   set_emax (e);
1116   mpfr_inits2 (16, x, y, (mpfr_ptr) 0);
1117   mpq_init (q);
1118 
1119   mpfr_set_inf (x, 1);
1120   mpfr_nextbelow (x);
1121   mpq_set_ui (q, 1, 1);
1122 
1123   for (sign = 0; sign <= 1; sign++)
1124     {
1125       for (sub = 0; sub <= 1; sub++)
1126         {
1127           RND_LOOP(rnd)
1128             {
1129               unsigned int flags, ex_flags;
1130               int inf;
1131 
1132               inf = rnd == MPFR_RNDA ||
1133                     rnd == (sign ? MPFR_RNDD : MPFR_RNDU);
1134               ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0);
1135               mpfr_clear_flags ();
1136               inex = sub ?
1137                 mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) :
1138                 mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd);
1139               flags = __gmpfr_flags;
1140               if (inex == 0 || flags != ex_flags ||
1141                   (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y)))
1142                 {
1143                   printf ("Error in addsubq_overflow_aux(%ld),"
1144                           " sign = %d, %s\n", (long) e, sign,
1145                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
1146                   printf ("Got inex = %d, y = ", inex);
1147                   mpfr_dump (y);
1148                   printf ("Expected flags:");
1149                   flags_out (ex_flags);
1150                   printf ("Got flags:     ");
1151                   flags_out (flags);
1152                   exit (1);
1153                 }
1154             }
1155           mpq_neg (q, q);
1156         }
1157       mpfr_neg (x, x, MPFR_RNDN);
1158       mpq_neg (q, q);
1159     }
1160 
1161   mpq_clear (q);
1162   mpfr_clears (x, y, (mpfr_ptr) 0);
1163   set_emax (emax);
1164 }
1165 
1166 static void
1167 addsubq_overflow (void)
1168 {
1169   addsubq_overflow_aux (4913);
1170   addsubq_overflow_aux (MPFR_EMAX_MAX);
1171 }
1172 
1173 static void
1174 coverage_mpfr_mul_q_20110218 (void)
1175 {
1176   mpfr_t cmp, res, op1;
1177   mpq_t op2;
1178   int status;
1179 
1180   mpfr_init2 (cmp, MPFR_PREC_MIN);
1181   mpfr_init2 (res, MPFR_PREC_MIN);
1182   mpfr_init_set_si (op1, 1, MPFR_RNDN);
1183 
1184   mpq_init (op2);
1185   mpq_set_si (op2, 0, 0);
1186   mpz_set_si (mpq_denref (op2), 0);
1187 
1188   status = mpfr_mul_q (res, op1, op2, MPFR_RNDN);
1189 
1190   if ((status != 0) || (mpfr_cmp (cmp, res) != 0))
1191     {
1192       printf ("Results differ %d.\nres=", status);
1193       mpfr_print_binary (res);
1194       printf ("\ncmp=");
1195       mpfr_print_binary (cmp);
1196       putchar ('\n');
1197       exit (1);
1198     }
1199 
1200   mpfr_set_si (op1, 1, MPFR_RNDN);
1201   mpq_set_si (op2, -1, 0);
1202 
1203   status = mpfr_mul_q (res, op1, op2, MPFR_RNDN);
1204 
1205   mpfr_set_inf (cmp, -1);
1206   if ((status != 0) || (mpfr_cmp(res, cmp) != 0))
1207     {
1208       printf ("mpfr_mul_q 1 * (-1/0) returned a wrong value :\n waiting for ");
1209       mpfr_print_binary (cmp);
1210       printf (" got ");
1211       mpfr_print_binary (res);
1212       printf ("\n trinary value is %d\n", status);
1213       exit (1);
1214     }
1215 
1216   mpq_clear (op2);
1217   mpfr_clear (op1);
1218   mpfr_clear (res);
1219   mpfr_clear (cmp);
1220 }
1221 
1222 int
1223 main (int argc, char *argv[])
1224 {
1225   tests_start_mpfr ();
1226 
1227   special ();
1228 
1229   test_specialz (mpfr_add_z, mpz_add, "add");
1230   test_specialz (mpfr_sub_z, mpz_sub, "sub");
1231   test_specialz (mpfr_mul_z, mpz_mul, "mul");
1232   test_genericz (2, 100, 100, mpfr_add_z, "add");
1233   test_genericz (2, 100, 100, mpfr_sub_z, "sub");
1234   test_genericz (2, 100, 100, mpfr_mul_z, "mul");
1235   test_genericz (2, 100, 100, mpfr_div_z, "div");
1236   test_special2z (mpfr_z_sub, mpz_sub, "sub");
1237   test_generic2z (2, 100, 100, mpfr_z_sub, "sub");
1238 
1239   test_genericq (2, 100, 100, mpfr_add_q, "add");
1240   test_genericq (2, 100, 100, mpfr_sub_q, "sub");
1241   test_genericq (2, 100, 100, mpfr_mul_q, "mul");
1242   test_genericq (2, 100, 100, mpfr_div_q, "div");
1243   test_specialq (2, 100, 100, mpfr_mul_q, mpq_mul, "mul");
1244   test_specialq (2, 100, 100, mpfr_div_q, mpq_div, "div");
1245   test_specialq (2, 100, 100, mpfr_add_q, mpq_add, "add");
1246   test_specialq (2, 100, 100, mpfr_sub_q, mpq_sub, "sub");
1247 
1248   test_cmp_z (2, 100, 100);
1249   test_cmp_q (2, 100, 100);
1250   test_cmp_f (2, 100, 100);
1251 
1252   check_for_zero ();
1253 
1254   bug_mul_q_20100810 ();
1255   bug_div_q_20100810 ();
1256   bug_mul_div_q_20100818 ();
1257   reduced_expo_range ();
1258   addsubq_overflow ();
1259 
1260   coverage_mpfr_mul_q_20110218 ();
1261 
1262   tests_end_mpfr ();
1263   return 0;
1264 }
1265 
1266