Home | History | Annotate | Line # | Download | only in tests
tgmpop.c revision 1.1
      1 /* Test file for mpfr_add_[q,z], mpfr_sub_[q,z], mpfr_div_[q,z], mpfr_mul_[q,z]
      2    and mpfr_cmp_[q,z]
      3 
      4 Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      5 Contributed by the Arenaire and Cacao 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 " str ". Inexact value=%d\n", res); \
     31   printf ("Get "); mpfr_dump (y);                                 \
     32   printf ("X=  "); mpfr_dump (x);                                 \
     33   printf ("Z=  "); mpz_dump (mpq_numref(z));                      \
     34   printf ("   /"); mpz_dump (mpq_denref(z));                      \
     35   exit (1);                                                       \
     36 }
     37 
     38 static void
     39 special (void)
     40 {
     41   mpfr_t x, y;
     42   mpq_t z;
     43   int res = 0;
     44 
     45   mpfr_init (x);
     46   mpfr_init (y);
     47   mpq_init (z);
     48 
     49   /* cancellation in mpfr_add_q */
     50   mpfr_set_prec (x, 60);
     51   mpfr_set_prec (y, 20);
     52   mpz_set_str (mpq_numref (z), "-187207494", 10);
     53   mpz_set_str (mpq_denref (z), "5721", 10);
     54   mpfr_set_str_binary (x, "11111111101001011011100101100011011110010011100010000100001E-44");
     55   mpfr_add_q (y, x, z, MPFR_RNDN);
     56   CHECK_FOR ("cancelation in add_q", mpfr_cmp_ui_2exp (y, 256783, -64) == 0);
     57 
     58   mpfr_set_prec (x, 19);
     59   mpfr_set_str_binary (x, "0.1011110101110011100E0");
     60   mpz_set_str (mpq_numref (z), "187207494", 10);
     61   mpz_set_str (mpq_denref (z), "5721", 10);
     62   mpfr_set_prec (y, 29);
     63   mpfr_add_q (y, x, z, MPFR_RNDD);
     64   mpfr_set_prec (x, 29);
     65   mpfr_set_str_binary (x, "11111111101001110011010001001E-14");
     66   CHECK_FOR ("cancelation in add_q", mpfr_cmp (x,y) == 0);
     67 
     68   /* Inf */
     69   mpfr_set_inf (x, 1);
     70   mpz_set_str (mpq_numref (z), "395877315", 10);
     71   mpz_set_str (mpq_denref (z), "3508975966", 10);
     72   mpfr_set_prec (y, 118);
     73   mpfr_add_q (y, x, z, MPFR_RNDU);
     74   CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
     75   mpfr_sub_q (y, x, z, MPFR_RNDU);
     76   CHECK_FOR ("inf", mpfr_inf_p (y) && mpfr_sgn (y) > 0);
     77 
     78   /* Nan */
     79   MPFR_SET_NAN (x);
     80   mpfr_add_q (y, x, z, MPFR_RNDU);
     81   CHECK_FOR ("nan", mpfr_nan_p (y));
     82   mpfr_sub_q (y, x, z, MPFR_RNDU);
     83   CHECK_FOR ("nan", mpfr_nan_p (y));
     84 
     85   /* Exact value */
     86   mpfr_set_prec (x, 60);
     87   mpfr_set_prec (y, 60);
     88   mpfr_set_str1 (x, "0.5");
     89   mpz_set_str (mpq_numref (z), "3", 10);
     90   mpz_set_str (mpq_denref (z), "2", 10);
     91   res = mpfr_add_q (y, x, z, MPFR_RNDU);
     92   CHECK_FOR ("0.5+3/2", mpfr_cmp_ui(y, 2)==0 && res==0);
     93   res = mpfr_sub_q (y, x, z, MPFR_RNDU);
     94   CHECK_FOR ("0.5-3/2", mpfr_cmp_si(y, -1)==0 && res==0);
     95 
     96   /* Inf Rationnal */
     97   mpq_set_ui (z, 1, 0);
     98   mpfr_set_str1 (x, "0.5");
     99   res = mpfr_add_q (y, x, z, MPFR_RNDN);
    100   CHECK_FOR ("0.5+1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
    101   res = mpfr_sub_q (y, x, z, MPFR_RNDN);
    102   CHECK_FOR ("0.5-1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
    103   mpq_set_si (z, -1, 0);
    104   res = mpfr_add_q (y, x, z, MPFR_RNDN);
    105   CHECK_FOR ("0.5+ -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) < 0 && res == 0);
    106   res = mpfr_sub_q (y, x, z, MPFR_RNDN);
    107   CHECK_FOR ("0.5- -1/0", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
    108   res = mpfr_div_q (y, x, z, MPFR_RNDN);
    109   CHECK_FOR ("0.5 / (-1/0)", mpfr_zero_p (y) && MPFR_SIGN (y) < 0 && res == 0);
    110 
    111   /* 0 */
    112   mpq_set_ui (z, 0, 1);
    113   mpfr_set_ui (x, 42, MPFR_RNDN);
    114   res = mpfr_add_q (y, x, z, MPFR_RNDN);
    115   CHECK_FOR ("42+0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
    116   res = mpfr_sub_q (y, x, z, MPFR_RNDN);
    117   CHECK_FOR ("42-0/1", mpfr_cmp_ui (y, 42) == 0 && res == 0);
    118   res = mpfr_mul_q (y, x, z, MPFR_RNDN);
    119   CHECK_FOR ("42*0/1", mpfr_zero_p (y) && MPFR_SIGN (y) > 0 && res == 0);
    120   res = mpfr_div_q (y, x, z, MPFR_RNDN);
    121   CHECK_FOR ("42/(0/1)", mpfr_inf_p (y) && MPFR_SIGN (y) > 0 && res == 0);
    122 
    123 
    124   mpq_clear (z);
    125   mpfr_clear (x);
    126   mpfr_clear (y);
    127 }
    128 
    129 static void
    130 check_for_zero (void)
    131 {
    132   /* Check that 0 is unsigned! */
    133   mpq_t q;
    134   mpz_t z;
    135   mpfr_t x;
    136   int r;
    137   mpfr_sign_t i;
    138 
    139   mpfr_init (x);
    140   mpz_init (z);
    141   mpq_init (q);
    142 
    143   mpz_set_ui (z, 0);
    144   mpq_set_ui (q, 0, 1);
    145 
    146   MPFR_SET_ZERO (x);
    147   RND_LOOP (r)
    148     {
    149       for (i = MPFR_SIGN_NEG ; i <= MPFR_SIGN_POS ;
    150            i+=MPFR_SIGN_POS-MPFR_SIGN_NEG)
    151         {
    152           MPFR_SET_SIGN(x, i);
    153           mpfr_add_z (x, x, z, (mpfr_rnd_t) r);
    154           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
    155             {
    156               printf("GMP Zero errors for add_z & rnd=%s & s=%d\n",
    157                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    158               mpfr_dump (x);
    159               exit (1);
    160             }
    161           mpfr_sub_z (x, x, z, (mpfr_rnd_t) r);
    162           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
    163             {
    164               printf("GMP Zero errors for sub_z & rnd=%s & s=%d\n",
    165                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    166               mpfr_dump (x);
    167               exit (1);
    168             }
    169           mpfr_mul_z (x, x, z, (mpfr_rnd_t) r);
    170           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
    171             {
    172               printf("GMP Zero errors for mul_z & rnd=%s & s=%d\n",
    173                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    174               mpfr_dump (x);
    175               exit (1);
    176             }
    177           mpfr_add_q (x, x, q, (mpfr_rnd_t) r);
    178           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
    179             {
    180               printf("GMP Zero errors for add_q & rnd=%s & s=%d\n",
    181                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    182               mpfr_dump (x);
    183               exit (1);
    184             }
    185           mpfr_sub_q (x, x, q, (mpfr_rnd_t) r);
    186           if (!MPFR_IS_ZERO(x) || MPFR_SIGN(x)!=i)
    187             {
    188               printf("GMP Zero errors for sub_q & rnd=%s & s=%d\n",
    189                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    190               mpfr_dump (x);
    191               exit (1);
    192              }
    193         }
    194     }
    195 
    196   mpq_clear (q);
    197   mpz_clear (z);
    198   mpfr_clear (x);
    199 }
    200 
    201 static void
    202 test_cmp_z (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
    203 {
    204   mpfr_t x, z;
    205   mpz_t  y;
    206   mpfr_prec_t p;
    207   int res1, res2;
    208   int n;
    209 
    210   mpfr_init (x);
    211   mpfr_init2 (z, MPFR_PREC_MIN);
    212   mpz_init (y);
    213   for(p=pmin ; p < pmax ; p++)
    214     {
    215       mpfr_set_prec (x, p);
    216       for ( n = 0; n < nmax ; n++)
    217         {
    218           mpfr_urandomb (x, RANDS);
    219           mpz_urandomb  (y, RANDS, 1024);
    220           if (!MPFR_IS_SINGULAR (x))
    221             {
    222               mpfr_sub_z (z, x, y, MPFR_RNDN);
    223               res1 = mpfr_sgn (z);
    224               res2 = mpfr_cmp_z (x, y);
    225               if (res1 != res2)
    226                 {
    227                   printf("Error for mpfr_cmp_z: res=%d sub_z gives %d\n",
    228                          res2, res1);
    229                   exit (1);
    230                 }
    231             }
    232         }
    233     }
    234   mpz_clear (y);
    235   mpfr_clear (x);
    236   mpfr_clear (z);
    237 }
    238 
    239 static void
    240 test_cmp_q (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
    241 {
    242   mpfr_t x, z;
    243   mpq_t  y;
    244   mpfr_prec_t p;
    245   int res1, res2;
    246   int n;
    247 
    248   mpfr_init (x);
    249   mpfr_init2 (z, MPFR_PREC_MIN);
    250   mpq_init (y);
    251   for(p=pmin ; p < pmax ; p++)
    252     {
    253       mpfr_set_prec (x, p);
    254       for (n = 0 ; n < nmax ; n++)
    255         {
    256           mpfr_urandomb (x, RANDS);
    257           mpq_set_ui (y, randlimb (), randlimb() );
    258           if (!MPFR_IS_SINGULAR (x))
    259             {
    260               mpfr_sub_q (z, x, y, MPFR_RNDN);
    261               res1 = mpfr_sgn (z);
    262               res2 = mpfr_cmp_q (x, y);
    263               if (res1 != res2)
    264                 {
    265                   printf("Error for mpfr_cmp_q: res=%d sub_z gives %d\n",
    266                          res2, res1);
    267                   exit (1);
    268                 }
    269             }
    270         }
    271     }
    272   mpq_clear (y);
    273   mpfr_clear (x);
    274   mpfr_clear (z);
    275 }
    276 
    277 static void
    278 test_cmp_f (mpfr_prec_t pmin, mpfr_prec_t pmax, int nmax)
    279 {
    280   mpfr_t x, z;
    281   mpf_t  y;
    282   mpfr_prec_t p;
    283   int res1, res2;
    284   int n;
    285 
    286   mpfr_init (x);
    287   mpfr_init2 (z, pmax+GMP_NUMB_BITS);
    288   mpf_init2 (y, MPFR_PREC_MIN);
    289   for(p=pmin ; p < pmax ; p+=3)
    290     {
    291       mpfr_set_prec (x, p);
    292       mpf_set_prec (y, p);
    293       for ( n = 0; n < nmax ; n++)
    294         {
    295           mpfr_urandomb (x, RANDS);
    296           mpf_urandomb  (y, RANDS, p);
    297           if (!MPFR_IS_SINGULAR (x))
    298             {
    299               mpfr_set_f (z, y, MPFR_RNDN);
    300               mpfr_sub   (z, x, z, MPFR_RNDN);
    301               res1 = mpfr_sgn (z);
    302               res2 = mpfr_cmp_f (x, y);
    303               if (res1 != res2)
    304                 {
    305                   printf("Error for mpfr_cmp_f: res=%d sub gives %d\n",
    306                          res2, res1);
    307                   exit (1);
    308                 }
    309             }
    310         }
    311     }
    312   mpf_clear (y);
    313   mpfr_clear (x);
    314   mpfr_clear (z);
    315 }
    316 
    317 static void
    318 test_specialz (int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
    319                void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
    320                const char *op)
    321 {
    322   mpfr_t x1, x2;
    323   mpz_t  z1, z2;
    324   int res;
    325 
    326   mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
    327   mpz_init (z1); mpz_init(z2);
    328   mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
    329   mpz_add_ui (z1, z1, 1);
    330   mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
    331   mpz_add_ui (z2, z2, 1);
    332 
    333   res = mpfr_set_z(x1, z1, MPFR_RNDN);
    334   if (res)
    335     {
    336       printf("Specialz %s: set_z1 error\n", op);
    337       exit(1);
    338     }
    339   mpfr_set_z (x2, z2, MPFR_RNDN);
    340   if (res)
    341     {
    342       printf("Specialz %s: set_z2 error\n", op);
    343       exit(1);
    344     }
    345 
    346   /* (19!+1) * (20!+1) fits in a 128 bits number */
    347   res = mpfr_func(x1, x1, z2, MPFR_RNDN);
    348   if (res)
    349     {
    350       printf("Specialz %s: wrong inexact flag.\n", op);
    351       exit(1);
    352     }
    353   mpz_func(z1, z1, z2);
    354   res = mpfr_set_z (x2, z1, MPFR_RNDN);
    355   if (res)
    356     {
    357       printf("Specialz %s: set_z2 error\n", op);
    358       exit(1);
    359     }
    360   if (mpfr_cmp(x1, x2))
    361     {
    362       printf("Specialz %s: results differ.\nx1=", op);
    363       mpfr_print_binary(x1);
    364       printf("\nx2=");
    365       mpfr_print_binary(x2);
    366       printf ("\nZ2=");
    367       mpz_out_str (stdout, 2, z1);
    368       putchar('\n');
    369       exit(1);
    370     }
    371 
    372   mpz_set_ui (z1, 1);
    373   mpz_set_ui (z2, 0);
    374   mpfr_set_ui (x1, 1, MPFR_RNDN);
    375   mpz_func (z1, z1, z2);
    376   res = mpfr_func(x1, x1, z2, MPFR_RNDN);
    377   mpfr_set_z (x2, z1, MPFR_RNDN);
    378   if (mpfr_cmp(x1, x2))
    379     {
    380       printf("Specialz %s: results differ(2).\nx1=", op);
    381       mpfr_print_binary(x1);
    382       printf("\nx2=");
    383       mpfr_print_binary(x2);
    384       putchar('\n');
    385       exit(1);
    386     }
    387 
    388   mpz_clear (z1); mpz_clear(z2);
    389   mpfr_clears (x1, x2, (mpfr_ptr) 0);
    390 }
    391 
    392 static void
    393 test_genericz (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
    394                int (*func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t),
    395                const char *op)
    396 {
    397   mpfr_prec_t prec;
    398   mpfr_t arg1, dst_big, dst_small, tmp;
    399   mpz_t  arg2;
    400   mpfr_rnd_t rnd;
    401   int inexact, compare, compare2;
    402   unsigned int n;
    403 
    404   mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
    405   mpz_init (arg2);
    406 
    407   for (prec = p0; prec <= p1; prec++)
    408     {
    409       mpfr_set_prec (arg1, prec);
    410       mpfr_set_prec (tmp, prec);
    411       mpfr_set_prec (dst_small, prec);
    412 
    413       for (n=0; n<N; n++)
    414         {
    415           mpfr_urandomb (arg1, RANDS);
    416           mpz_urandomb (arg2, RANDS, 1024);
    417           rnd = RND_RAND ();
    418           mpfr_set_prec (dst_big, 2*prec);
    419           compare = func(dst_big, arg1, arg2, rnd);
    420           if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec))
    421             {
    422               mpfr_set (tmp, dst_big, rnd);
    423               inexact = func(dst_small, arg1, arg2, rnd);
    424               if (mpfr_cmp (tmp, dst_small))
    425                 {
    426                   printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n"
    427                           "arg1=",
    428                           (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
    429                   mpfr_print_binary (arg1);
    430                   printf("\narg2=");
    431                   mpz_out_str (stdout, 2, arg2);
    432                   printf ("\ngot      ");
    433                   mpfr_dump (dst_small);
    434                   printf ("expected ");
    435                   mpfr_dump (tmp);
    436                   printf ("approx   ");
    437                   mpfr_dump (dst_big);
    438                   exit (1);
    439                 }
    440               compare2 = mpfr_cmp (tmp, dst_big);
    441               /* if rounding to nearest, cannot know the sign of t - f(x)
    442                  because of composed rounding: y = o(f(x)) and t = o(y) */
    443               if (compare * compare2 >= 0)
    444                 compare = compare + compare2;
    445               else
    446                 compare = inexact; /* cannot determine sign(t-f(x)) */
    447               if (((inexact == 0) && (compare != 0)) ||
    448                   ((inexact > 0) && (compare <= 0)) ||
    449                   ((inexact < 0) && (compare >= 0)))
    450                 {
    451                   printf ("Wrong inexact flag for rnd=%s and %s_z:\n"
    452                           "expected %d, got %d\n",
    453                           mpfr_print_rnd_mode (rnd), op, compare, inexact);
    454                   printf ("\narg1="); mpfr_print_binary (arg1);
    455                   printf ("\narg2="); mpz_out_str(stdout, 2, arg2);
    456                   printf ("\ndstl="); mpfr_print_binary (dst_big);
    457                   printf ("\ndsts="); mpfr_print_binary (dst_small);
    458                   printf ("\ntmp ="); mpfr_dump (tmp);
    459                   exit (1);
    460                 }
    461             }
    462         }
    463     }
    464 
    465   mpz_clear (arg2);
    466   mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
    467 }
    468 
    469 static void
    470 test_genericq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
    471                int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
    472                const char *op)
    473 {
    474   mpfr_prec_t prec;
    475   mpfr_t arg1, dst_big, dst_small, tmp;
    476   mpq_t  arg2;
    477   mpfr_rnd_t rnd;
    478   int inexact, compare, compare2;
    479   unsigned int n;
    480 
    481   mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
    482   mpq_init (arg2);
    483 
    484   for (prec = p0; prec <= p1; prec++)
    485     {
    486       mpfr_set_prec (arg1, prec);
    487       mpfr_set_prec (tmp, prec);
    488       mpfr_set_prec (dst_small, prec);
    489 
    490       for (n=0; n<N; n++)
    491         {
    492           mpfr_urandomb (arg1, RANDS);
    493           mpq_set_ui (arg2, randlimb (), randlimb() );
    494           mpq_canonicalize (arg2);
    495           rnd = RND_RAND ();
    496           mpfr_set_prec (dst_big, prec+10);
    497           compare = func(dst_big, arg1, arg2, rnd);
    498           if (mpfr_can_round (dst_big, prec+10, rnd, rnd, prec))
    499             {
    500               mpfr_set (tmp, dst_big, rnd);
    501               inexact = func(dst_small, arg1, arg2, rnd);
    502               if (mpfr_cmp (tmp, dst_small))
    503                 {
    504                   printf ("Results differ for prec=%u rnd_mode=%s and %s_q:\n"
    505                           "arg1=",
    506                           (unsigned) prec, mpfr_print_rnd_mode (rnd), op);
    507                   mpfr_print_binary (arg1);
    508                   printf("\narg2=");
    509                   mpq_out_str(stdout, 2, arg2);
    510                   printf ("\ngot      ");
    511                   mpfr_print_binary (dst_small);
    512                   printf ("\nexpected ");
    513                   mpfr_print_binary (tmp);
    514                   printf ("\napprox  ");
    515                   mpfr_print_binary (dst_big);
    516                   putchar('\n');
    517                   exit (1);
    518                 }
    519               compare2 = mpfr_cmp (tmp, dst_big);
    520               /* if rounding to nearest, cannot know the sign of t - f(x)
    521                  because of composed rounding: y = o(f(x)) and t = o(y) */
    522               if (compare * compare2 >= 0)
    523                 compare = compare + compare2;
    524               else
    525                 compare = inexact; /* cannot determine sign(t-f(x)) */
    526               if (((inexact == 0) && (compare != 0)) ||
    527                   ((inexact > 0) && (compare <= 0)) ||
    528                   ((inexact < 0) && (compare >= 0)))
    529                 {
    530                   printf ("Wrong inexact flag for rnd=%s and %s_q:\n"
    531                           "expected %d, got %d",
    532                           mpfr_print_rnd_mode (rnd), op, compare, inexact);
    533                   printf ("\narg1="); mpfr_print_binary (arg1);
    534                   printf ("\narg2="); mpq_out_str(stdout, 2, arg2);
    535                   printf ("\ndstl="); mpfr_print_binary (dst_big);
    536                   printf ("\ndsts="); mpfr_print_binary (dst_small);
    537                   printf ("\ntmp ="); mpfr_print_binary (tmp);
    538                   putchar('\n');
    539                   exit (1);
    540                 }
    541             }
    542         }
    543     }
    544 
    545   mpq_clear (arg2);
    546   mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0);
    547 }
    548 
    549 static void
    550 test_specialq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N,
    551                int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t),
    552                void (*mpq_func)(mpq_ptr, mpq_srcptr, mpq_srcptr),
    553                const char *op)
    554 {
    555   mpfr_t fra, frb, frq;
    556   mpq_t  q1, q2, qr;
    557   unsigned int n;
    558   mpfr_prec_t prec;
    559 
    560   for (prec = p0 ; prec < p1 ; prec++)
    561     {
    562       mpfr_inits2 (prec, fra, frb, frq, (mpfr_ptr) 0);
    563       mpq_init (q1); mpq_init(q2); mpq_init (qr);
    564 
    565       for( n = 0 ; n < N ; n++)
    566         {
    567           mpq_set_ui(q1, randlimb(), randlimb() );
    568           mpq_set_ui(q2, randlimb(), randlimb() );
    569           mpq_canonicalize (q1);
    570           mpq_canonicalize (q2);
    571           mpq_func (qr, q1, q2);
    572           mpfr_set_q (fra, q1, MPFR_RNDD);
    573           mpfr_func (fra, fra, q2, MPFR_RNDD);
    574           mpfr_set_q (frb, q1, MPFR_RNDU);
    575           mpfr_func (frb, frb, q2, MPFR_RNDU);
    576           mpfr_set_q (frq, qr, MPFR_RNDN);
    577           /* We should have fra <= qr <= frb */
    578           if ( (mpfr_cmp(fra, frq) > 0) || (mpfr_cmp (frq, frb) > 0))
    579             {
    580               printf("Range error for prec=%lu and %s", prec, op);
    581               printf ("\nq1="); mpq_out_str(stdout, 2, q1);
    582               printf ("\nq2="); mpq_out_str(stdout, 2, q2);
    583               printf ("\nfr_dn="); mpfr_print_binary (fra);
    584               printf ("\nfr_q ="); mpfr_print_binary (frq);
    585               printf ("\nfr_up="); mpfr_print_binary (frb);
    586               putchar('\n');
    587               exit (1);
    588             }
    589         }
    590 
    591       mpq_clear (q1); mpq_clear (q2); mpq_clear (qr);
    592       mpfr_clears (fra, frb, frq, (mpfr_ptr) 0);
    593     }
    594 }
    595 
    596 int
    597 main (int argc, char *argv[])
    598 {
    599   tests_start_mpfr ();
    600 
    601   special ();
    602 
    603   test_specialz (mpfr_add_z, mpz_add, "add");
    604   test_specialz (mpfr_sub_z, mpz_sub, "sub");
    605   test_specialz (mpfr_mul_z, mpz_mul, "mul");
    606   test_genericz (2, 100, 100, mpfr_add_z, "add");
    607   test_genericz (2, 100, 100, mpfr_sub_z, "sub");
    608   test_genericz (2, 100, 100, mpfr_mul_z, "mul");
    609   test_genericz (2, 100, 100, mpfr_div_z, "div");
    610 
    611   test_genericq (2, 100, 100, mpfr_add_q, "add");
    612   test_genericq (2, 100, 100, mpfr_sub_q, "sub");
    613   test_genericq (2, 100, 100, mpfr_mul_q, "mul");
    614   test_genericq (2, 100, 100, mpfr_div_q, "div");
    615   test_specialq (2, 100, 100, mpfr_mul_q, mpq_mul, "mul");
    616   test_specialq (2, 100, 100, mpfr_div_q, mpq_div, "div");
    617   test_specialq (2, 100, 100, mpfr_add_q, mpq_add, "add");
    618   test_specialq (2, 100, 100, mpfr_sub_q, mpq_sub, "sub");
    619 
    620   test_cmp_z (2, 100, 100);
    621   test_cmp_q (2, 100, 100);
    622   test_cmp_f (2, 100, 100);
    623 
    624   check_for_zero ();
    625 
    626   tests_end_mpfr ();
    627   return 0;
    628 }
    629 
    630