Home | History | Annotate | Line # | Download | only in tests
tgmpop.c revision 1.1.1.4
      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