tgmpop.c revision 1.1.1.3
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
4Copyright 2004-2016 Free Software Foundation, Inc.
5Contributed by the AriC and Caramba projects, INRIA.
6
7This file is part of the GNU MPFR Library.
8
9The GNU MPFR Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 3 of the License, or (at your
12option) any later version.
13
14The GNU MPFR Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
21http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2251 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
49static void
50special (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
171static void
172check_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
243static void
244test_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
295static void
296test_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
347static void
348test_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
401static void
402test_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
476static void
477test_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
551static void
552test_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
628static void
629test_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
705static void
706test_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
785static void
786test_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
833static void
834bug_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
877static void
878bug_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
921static void
922bug_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
1014static void
1015reduced_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
1103static void
1104addsubq_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
1166static void
1167addsubq_overflow (void)
1168{
1169  addsubq_overflow_aux (4913);
1170  addsubq_overflow_aux (MPFR_EMAX_MAX);
1171}
1172
1173static void
1174coverage_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
1222int
1223main (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