Home | History | Annotate | Line # | Download | only in tests
tgeneric.c revision 1.1.1.2
      1      1.1  mrg /* Generic test file for functions with one or two arguments (the second being
      2      1.1  mrg    either mpfr_t or double).
      3      1.1  mrg 
      4  1.1.1.2  mrg Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
      5  1.1.1.2  mrg Contributed by the AriC and Caramel projects, INRIA.
      6      1.1  mrg 
      7      1.1  mrg This file is part of the GNU MPFR Library.
      8      1.1  mrg 
      9      1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
     10      1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     11      1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     12      1.1  mrg option) any later version.
     13      1.1  mrg 
     14      1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     15      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16      1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     17      1.1  mrg License for more details.
     18      1.1  mrg 
     19      1.1  mrg You should have received a copy of the GNU Lesser General Public License
     20      1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     21      1.1  mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     22      1.1  mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     23      1.1  mrg 
     24      1.1  mrg /* define TWO_ARGS for two-argument functions like mpfr_pow
     25      1.1  mrg    define DOUBLE_ARG1 or DOUBLE_ARG2 for function with a double operand in
     26      1.1  mrg    first or second place like sub_d or d_sub */
     27      1.1  mrg 
     28      1.1  mrg #ifndef TEST_RANDOM_POS
     29      1.1  mrg /* For the random function: one number on two is negative. */
     30      1.1  mrg #define TEST_RANDOM_POS 256
     31      1.1  mrg #endif
     32      1.1  mrg 
     33      1.1  mrg #ifndef TEST_RANDOM_POS2
     34      1.1  mrg /* For the random function: one number on two is negative. */
     35      1.1  mrg #define TEST_RANDOM_POS2 256
     36      1.1  mrg #endif
     37      1.1  mrg 
     38      1.1  mrg #ifndef TEST_RANDOM_EMIN
     39      1.1  mrg #define TEST_RANDOM_EMIN -256
     40      1.1  mrg #endif
     41      1.1  mrg 
     42      1.1  mrg #ifndef TEST_RANDOM_EMAX
     43      1.1  mrg #define TEST_RANDOM_EMAX 255
     44      1.1  mrg #endif
     45      1.1  mrg 
     46  1.1.1.2  mrg /* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug,
     47  1.1.1.2  mrg    then define TGENERIC_SO_TEST with an adequate test (possibly 0) to
     48  1.1.1.2  mrg    omit this particular case. */
     49  1.1.1.2  mrg #ifndef TGENERIC_SO_TEST
     50  1.1.1.2  mrg #define TGENERIC_SO_TEST 1
     51  1.1.1.2  mrg #endif
     52  1.1.1.2  mrg 
     53  1.1.1.2  mrg #define STR(F) #F
     54  1.1.1.2  mrg #define MAKE_STR(S) STR(S)
     55  1.1.1.2  mrg 
     56      1.1  mrg /* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions
     57      1.1  mrg  * with 2 arguments. See <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>.
     58      1.1  mrg  */
     59      1.1  mrg #define TGENERIC_FAIL(S, X, U)                                          \
     60      1.1  mrg   do                                                                    \
     61      1.1  mrg     {                                                                   \
     62      1.1  mrg       printf ("%s\nx = ", (S));                                         \
     63  1.1.1.2  mrg       mpfr_out_str (stdout, 2, 0, (X), MPFR_RNDN);                      \
     64      1.1  mrg       printf ("\n");                                                    \
     65      1.1  mrg       if ((void *) U != 0)                                              \
     66      1.1  mrg         {                                                               \
     67      1.1  mrg           printf ("u = ");                                              \
     68  1.1.1.2  mrg           mpfr_out_str (stdout, 2, 0, (U), MPFR_RNDN);                  \
     69      1.1  mrg           printf ("\n");                                                \
     70      1.1  mrg         }                                                               \
     71      1.1  mrg       printf ("yprec = %u, rnd_mode = %s, inexact = %d, flags = %u\n",  \
     72      1.1  mrg               (unsigned int) yprec, mpfr_print_rnd_mode (rnd), compare, \
     73      1.1  mrg               (unsigned int) __gmpfr_flags);                            \
     74      1.1  mrg       exit (1);                                                         \
     75      1.1  mrg     }                                                                   \
     76      1.1  mrg   while (0)
     77      1.1  mrg 
     78  1.1.1.2  mrg #define TGENERIC_CHECK_AUX(S, EXPR, U)                        \
     79  1.1.1.2  mrg   do                                                          \
     80  1.1.1.2  mrg     if (!(EXPR))                                              \
     81  1.1.1.2  mrg       TGENERIC_FAIL (S " in " MAKE_STR(TEST_FUNCTION), x, U); \
     82  1.1.1.2  mrg   while (0)
     83  1.1.1.2  mrg 
     84      1.1  mrg #undef TGENERIC_CHECK
     85      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
     86  1.1.1.2  mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u)
     87      1.1  mrg #else
     88  1.1.1.2  mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0)
     89      1.1  mrg #endif
     90      1.1  mrg 
     91      1.1  mrg #ifdef DEBUG_TGENERIC
     92      1.1  mrg #define TGENERIC_IAUX(F,P,X,U)                                          \
     93      1.1  mrg   do                                                                    \
     94      1.1  mrg     {                                                                   \
     95      1.1  mrg       printf ("tgeneric: testing function " STR(F)                      \
     96      1.1  mrg               ", %s, target prec = %lu\nx = ",                          \
     97      1.1  mrg               mpfr_print_rnd_mode (rnd), (unsigned long) (P));          \
     98  1.1.1.2  mrg       mpfr_out_str (stdout, 2, 0, (X), MPFR_RNDN);                      \
     99      1.1  mrg       printf ("\n");                                                    \
    100      1.1  mrg       if (U)                                                            \
    101      1.1  mrg         {                                                               \
    102      1.1  mrg           printf ("u = ");                                              \
    103  1.1.1.2  mrg           mpfr_out_str (stdout, 2, 0, (U), MPFR_RNDN);                  \
    104      1.1  mrg           printf ("\n");                                                \
    105      1.1  mrg         }                                                               \
    106      1.1  mrg     }                                                                   \
    107      1.1  mrg   while (0)
    108      1.1  mrg #undef TGENERIC_INFO
    109      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    110      1.1  mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u)
    111      1.1  mrg #else
    112      1.1  mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0)
    113      1.1  mrg #endif
    114      1.1  mrg #endif
    115      1.1  mrg 
    116      1.1  mrg /* For some functions (for example cos), the argument reduction is too
    117      1.1  mrg    expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX
    118      1.1  mrg    to some reasonable value before including tgeneric.c. */
    119      1.1  mrg #ifndef REDUCE_EMAX
    120      1.1  mrg #define REDUCE_EMAX mpfr_get_emax ()
    121      1.1  mrg #endif
    122      1.1  mrg 
    123      1.1  mrg static void
    124  1.1.1.2  mrg test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
    125      1.1  mrg {
    126      1.1  mrg   mpfr_prec_t prec, xprec, yprec;
    127      1.1  mrg   mpfr_t x, y, z, t, w;
    128      1.1  mrg #ifdef TWO_ARGS
    129      1.1  mrg   mpfr_t u;
    130      1.1  mrg #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    131      1.1  mrg   mpfr_t u;
    132      1.1  mrg   double d;
    133      1.1  mrg #endif
    134      1.1  mrg   mpfr_rnd_t rnd;
    135      1.1  mrg   int inexact, compare, compare2;
    136      1.1  mrg   unsigned int n;
    137      1.1  mrg   unsigned long ctrt = 0, ctrn = 0;
    138      1.1  mrg   mpfr_exp_t old_emin, old_emax;
    139      1.1  mrg 
    140      1.1  mrg   old_emin = mpfr_get_emin ();
    141      1.1  mrg   old_emax = mpfr_get_emax ();
    142      1.1  mrg 
    143      1.1  mrg   mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
    144      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    145      1.1  mrg   mpfr_init2 (u, MPFR_PREC_MIN);
    146      1.1  mrg #endif
    147      1.1  mrg 
    148      1.1  mrg   /* generic test */
    149      1.1  mrg   for (prec = p0; prec <= p1; prec++)
    150      1.1  mrg     {
    151      1.1  mrg       mpfr_set_prec (z, prec);
    152      1.1  mrg       mpfr_set_prec (t, prec);
    153      1.1  mrg       yprec = prec + 10;
    154      1.1  mrg       mpfr_set_prec (y, yprec);
    155      1.1  mrg       mpfr_set_prec (w, yprec);
    156      1.1  mrg 
    157      1.1  mrg       /* Note: in precision p1, we test 4 special cases. */
    158  1.1.1.2  mrg       for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
    159      1.1  mrg         {
    160  1.1.1.2  mrg           int infinite_input = 0;
    161  1.1.1.2  mrg 
    162      1.1  mrg           xprec = prec;
    163      1.1  mrg           if (randlimb () & 1)
    164      1.1  mrg             {
    165      1.1  mrg               xprec *= (double) randlimb () / MP_LIMB_T_MAX;
    166      1.1  mrg               if (xprec < MPFR_PREC_MIN)
    167      1.1  mrg                 xprec = MPFR_PREC_MIN;
    168      1.1  mrg             }
    169      1.1  mrg           mpfr_set_prec (x, xprec);
    170      1.1  mrg #ifdef TWO_ARGS
    171      1.1  mrg           mpfr_set_prec (u, xprec);
    172      1.1  mrg #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    173      1.1  mrg           mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
    174      1.1  mrg #endif
    175      1.1  mrg 
    176      1.1  mrg           if (n > 3 || prec < p1)
    177      1.1  mrg             {
    178      1.1  mrg #if defined(RAND_FUNCTION)
    179      1.1  mrg               RAND_FUNCTION (x);
    180      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    181      1.1  mrg               RAND_FUNCTION (u);
    182      1.1  mrg #endif
    183      1.1  mrg #else
    184      1.1  mrg               tests_default_random (x, TEST_RANDOM_POS,
    185      1.1  mrg                                     TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
    186      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    187      1.1  mrg               tests_default_random (u, TEST_RANDOM_POS2,
    188      1.1  mrg                                     TEST_RANDOM_EMIN, TEST_RANDOM_EMAX);
    189      1.1  mrg #endif
    190      1.1  mrg #endif
    191      1.1  mrg             }
    192      1.1  mrg           else
    193      1.1  mrg             {
    194      1.1  mrg               /* Special cases tested in precision p1 if n <= 3. They are
    195      1.1  mrg                  useful really in the extended exponent range. */
    196  1.1.1.2  mrg #if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
    197  1.1.1.2  mrg               goto next_n;
    198  1.1.1.2  mrg #endif
    199      1.1  mrg               set_emin (MPFR_EMIN_MIN);
    200      1.1  mrg               set_emax (MPFR_EMAX_MAX);
    201      1.1  mrg               if (n <= 1)
    202      1.1  mrg                 {
    203      1.1  mrg                   mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
    204      1.1  mrg                   mpfr_set_exp (x, mpfr_get_emin ());
    205      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    206      1.1  mrg                   mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
    207      1.1  mrg                   mpfr_set_exp (u, mpfr_get_emin ());
    208      1.1  mrg #endif
    209      1.1  mrg                 }
    210      1.1  mrg               else  /* 2 <= n <= 3 */
    211      1.1  mrg                 {
    212      1.1  mrg                   if (getenv ("MPFR_CHECK_MAX") == NULL)
    213      1.1  mrg                     goto next_n;
    214      1.1  mrg                   mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
    215      1.1  mrg                   mpfr_setmax (x, REDUCE_EMAX);
    216      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    217      1.1  mrg                   mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
    218      1.1  mrg                   mpfr_setmax (u, mpfr_get_emax ());
    219      1.1  mrg #endif
    220      1.1  mrg                 }
    221      1.1  mrg             }
    222      1.1  mrg 
    223      1.1  mrg           rnd = RND_RAND ();
    224      1.1  mrg           mpfr_clear_flags ();
    225      1.1  mrg #ifdef DEBUG_TGENERIC
    226      1.1  mrg           TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
    227      1.1  mrg #endif
    228      1.1  mrg #if defined(TWO_ARGS)
    229      1.1  mrg           compare = TEST_FUNCTION (y, x, u, rnd);
    230      1.1  mrg #elif defined(DOUBLE_ARG1)
    231      1.1  mrg           d = mpfr_get_d (u, rnd);
    232      1.1  mrg           compare = TEST_FUNCTION (y, d, x, rnd);
    233  1.1.1.2  mrg           /* d can be infinite due to overflow in mpfr_get_d */
    234  1.1.1.2  mrg           infinite_input |= DOUBLE_ISINF (d);
    235      1.1  mrg #elif defined(DOUBLE_ARG2)
    236      1.1  mrg           d = mpfr_get_d (u, rnd);
    237      1.1  mrg           compare = TEST_FUNCTION (y, x, d, rnd);
    238  1.1.1.2  mrg           /* d can be infinite due to overflow in mpfr_get_d */
    239  1.1.1.2  mrg           infinite_input |= DOUBLE_ISINF (d);
    240      1.1  mrg #else
    241      1.1  mrg           compare = TEST_FUNCTION (y, x, rnd);
    242      1.1  mrg #endif
    243      1.1  mrg           TGENERIC_CHECK ("Bad inexact flag",
    244      1.1  mrg                           (compare != 0) ^ (mpfr_inexflag_p () == 0));
    245      1.1  mrg           ctrt++;
    246      1.1  mrg           /* Consistency test in a reduced exponent range. Doing it
    247      1.1  mrg              for the first 10 samples and for prec == p1 (which has
    248      1.1  mrg              some special cases) should be sufficient. */
    249      1.1  mrg           if (ctrt <= 10 || prec == p1)
    250      1.1  mrg             {
    251      1.1  mrg               unsigned int flags, oldflags = __gmpfr_flags;
    252      1.1  mrg               mpfr_exp_t e, emin, emax, oemin, oemax;
    253      1.1  mrg 
    254      1.1  mrg               /* Determine the smallest exponent range containing the
    255      1.1  mrg                  exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
    256      1.1  mrg                  and output (y). */
    257      1.1  mrg               emin = MPFR_EMAX_MAX;
    258      1.1  mrg               emax = MPFR_EMIN_MIN;
    259      1.1  mrg               if (MPFR_IS_PURE_FP (x))
    260      1.1  mrg                 {
    261      1.1  mrg                   e = MPFR_GET_EXP (x);
    262      1.1  mrg                   if (e < emin)
    263      1.1  mrg                     emin = e;
    264      1.1  mrg                   if (e > emax)
    265      1.1  mrg                     emax = e;
    266      1.1  mrg                 }
    267      1.1  mrg               if (MPFR_IS_PURE_FP (y))
    268      1.1  mrg                 {
    269      1.1  mrg                   e = MPFR_GET_EXP (y);
    270      1.1  mrg                   if (e < emin)
    271      1.1  mrg                     emin = e;
    272      1.1  mrg                   if (e > emax)
    273      1.1  mrg                     emax = e;
    274      1.1  mrg                 }
    275      1.1  mrg #if defined(TWO_ARGS)
    276      1.1  mrg               if (MPFR_IS_PURE_FP (u))
    277      1.1  mrg                 {
    278      1.1  mrg                   e = MPFR_GET_EXP (u);
    279      1.1  mrg                   if (e < emin)
    280      1.1  mrg                     emin = e;
    281      1.1  mrg                   if (e > emax)
    282      1.1  mrg                     emax = e;
    283      1.1  mrg                 }
    284      1.1  mrg #endif
    285      1.1  mrg               if (emin > emax)
    286      1.1  mrg                 emin = emax;  /* case where all values are singular */
    287      1.1  mrg               oemin = mpfr_get_emin ();
    288      1.1  mrg               oemax = mpfr_get_emax ();
    289      1.1  mrg               mpfr_set_emin (emin);
    290      1.1  mrg               mpfr_set_emax (emax);
    291  1.1.1.2  mrg #ifdef DEBUG_TGENERIC
    292  1.1.1.2  mrg               /* Useful information in case of assertion failure. */
    293  1.1.1.2  mrg               printf ("tgeneric: reduced exponent range [%"
    294  1.1.1.2  mrg                       MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
    295  1.1.1.2  mrg                       (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
    296  1.1.1.2  mrg #endif
    297      1.1  mrg               mpfr_clear_flags ();
    298      1.1  mrg #if defined(TWO_ARGS)
    299      1.1  mrg               inexact = TEST_FUNCTION (w, x, u, rnd);
    300      1.1  mrg #elif defined(DOUBLE_ARG1)
    301      1.1  mrg               inexact = TEST_FUNCTION (w, d, x, rnd);
    302      1.1  mrg #elif defined(DOUBLE_ARG2)
    303      1.1  mrg               inexact = TEST_FUNCTION (w, x, d, rnd);
    304      1.1  mrg #else
    305      1.1  mrg               inexact = TEST_FUNCTION (w, x, rnd);
    306      1.1  mrg #endif
    307      1.1  mrg               flags = __gmpfr_flags;
    308      1.1  mrg               mpfr_set_emin (oemin);
    309      1.1  mrg               mpfr_set_emax (oemax);
    310      1.1  mrg               if (! (SAME_VAL (w, y) &&
    311      1.1  mrg                      SAME_SIGN (inexact, compare) &&
    312      1.1  mrg                      flags == oldflags))
    313      1.1  mrg                 {
    314  1.1.1.2  mrg                   printf ("Error in " MAKE_STR(TEST_FUNCTION)
    315  1.1.1.2  mrg                           ", reduced exponent range [%"
    316      1.1  mrg                           MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
    317      1.1  mrg                           (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
    318      1.1  mrg                   printf ("x = ");
    319      1.1  mrg                   mpfr_dump (x);
    320      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    321      1.1  mrg                   printf ("u = ");
    322      1.1  mrg                   mpfr_dump (u);
    323      1.1  mrg #endif
    324      1.1  mrg                   printf ("yprec = %u, rnd_mode = %s\n",
    325      1.1  mrg                           (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
    326      1.1  mrg                   printf ("Expected:\n  y = ");
    327      1.1  mrg                   mpfr_dump (y);
    328      1.1  mrg                   printf ("  inex = %d, flags = %u\n",
    329      1.1  mrg                           SIGN (compare), oldflags);
    330      1.1  mrg                   printf ("Got:\n  w = ");
    331      1.1  mrg                   mpfr_dump (w);
    332      1.1  mrg                   printf ("  inex = %d, flags = %u\n",
    333      1.1  mrg                           SIGN (inexact), flags);
    334      1.1  mrg                   exit (1);
    335      1.1  mrg                 }
    336      1.1  mrg             }
    337      1.1  mrg           if (MPFR_IS_SINGULAR (y))
    338      1.1  mrg             {
    339      1.1  mrg               if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
    340      1.1  mrg                 TGENERIC_CHECK ("Bad NaN flag",
    341      1.1  mrg                                 MPFR_IS_NAN (y) && mpfr_nanflag_p ());
    342      1.1  mrg               else if (MPFR_IS_INF (y))
    343  1.1.1.2  mrg                 {
    344  1.1.1.2  mrg                   TGENERIC_CHECK ("Bad overflow flag",
    345  1.1.1.2  mrg                                   (compare != 0) ^ (mpfr_overflow_p () == 0));
    346  1.1.1.2  mrg                   TGENERIC_CHECK ("Bad divide-by-zero flag",
    347  1.1.1.2  mrg                                   (compare == 0 && !infinite_input) ^
    348  1.1.1.2  mrg                                   (mpfr_divby0_p () == 0));
    349  1.1.1.2  mrg                 }
    350      1.1  mrg               else if (MPFR_IS_ZERO (y))
    351      1.1  mrg                 TGENERIC_CHECK ("Bad underflow flag",
    352      1.1  mrg                                 (compare != 0) ^ (mpfr_underflow_p () == 0));
    353      1.1  mrg             }
    354  1.1.1.2  mrg           else if (mpfr_divby0_p ())
    355  1.1.1.2  mrg             {
    356  1.1.1.2  mrg               TGENERIC_CHECK ("Both overflow and divide-by-zero",
    357  1.1.1.2  mrg                               ! mpfr_overflow_p ());
    358  1.1.1.2  mrg               TGENERIC_CHECK ("Both underflow and divide-by-zero",
    359  1.1.1.2  mrg                               ! mpfr_underflow_p ());
    360  1.1.1.2  mrg               TGENERIC_CHECK ("Bad compare value (divide-by-zero)",
    361  1.1.1.2  mrg                               compare == 0);
    362  1.1.1.2  mrg             }
    363      1.1  mrg           else if (mpfr_overflow_p ())
    364      1.1  mrg             {
    365  1.1.1.2  mrg               TGENERIC_CHECK ("Both underflow and overflow",
    366  1.1.1.2  mrg                               ! mpfr_underflow_p ());
    367      1.1  mrg               TGENERIC_CHECK ("Bad compare value (overflow)", compare != 0);
    368      1.1  mrg               mpfr_nexttoinf (y);
    369      1.1  mrg               TGENERIC_CHECK ("Should have been max MPFR number",
    370      1.1  mrg                               MPFR_IS_INF (y));
    371      1.1  mrg             }
    372      1.1  mrg           else if (mpfr_underflow_p ())
    373      1.1  mrg             {
    374      1.1  mrg               TGENERIC_CHECK ("Bad compare value (underflow)", compare != 0);
    375      1.1  mrg               mpfr_nexttozero (y);
    376      1.1  mrg               TGENERIC_CHECK ("Should have been min MPFR number",
    377      1.1  mrg                               MPFR_IS_ZERO (y));
    378      1.1  mrg             }
    379      1.1  mrg           else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
    380      1.1  mrg             {
    381      1.1  mrg               ctrn++;
    382      1.1  mrg               mpfr_set (t, y, rnd);
    383      1.1  mrg               /* Risk of failures are known when some flags are already set
    384      1.1  mrg                  before the function call. Do not set the erange flag, as
    385      1.1  mrg                  it will remain set after the function call and no checks
    386      1.1  mrg                  are performed in such a case (see the mpfr_erangeflag_p
    387      1.1  mrg                  test below). */
    388      1.1  mrg               if (randlimb () & 1)
    389      1.1  mrg                 __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
    390      1.1  mrg #ifdef DEBUG_TGENERIC
    391      1.1  mrg               TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
    392      1.1  mrg #endif
    393      1.1  mrg               /* Let's increase the precision of the inputs in a random way.
    394      1.1  mrg                  In most cases, this doesn't make any difference, but for
    395      1.1  mrg                  the mpfr_fmod bug fixed in r6230, this triggers the bug. */
    396      1.1  mrg               mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
    397      1.1  mrg                                MPFR_RNDN);
    398      1.1  mrg #if defined(TWO_ARGS)
    399      1.1  mrg               mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
    400      1.1  mrg                                MPFR_RNDN);
    401      1.1  mrg               inexact = TEST_FUNCTION (z, x, u, rnd);
    402      1.1  mrg #elif defined(DOUBLE_ARG1)
    403      1.1  mrg               inexact = TEST_FUNCTION (z, d, x, rnd);
    404      1.1  mrg #elif defined(DOUBLE_ARG2)
    405      1.1  mrg               inexact = TEST_FUNCTION (z, x, d, rnd);
    406      1.1  mrg #else
    407      1.1  mrg               inexact = TEST_FUNCTION (z, x, rnd);
    408      1.1  mrg #endif
    409      1.1  mrg               if (mpfr_erangeflag_p ())
    410      1.1  mrg                 goto next_n;
    411      1.1  mrg               if (mpfr_nan_p (z) || mpfr_cmp (t, z) != 0)
    412      1.1  mrg                 {
    413      1.1  mrg                   printf ("results differ for x=");
    414      1.1  mrg                   mpfr_out_str (stdout, 2, xprec, x, MPFR_RNDN);
    415      1.1  mrg #ifdef TWO_ARGS
    416      1.1  mrg                   printf ("\nu=");
    417      1.1  mrg                   mpfr_out_str (stdout, 2, xprec, u, MPFR_RNDN);
    418      1.1  mrg #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    419      1.1  mrg                   printf ("\nu=");
    420      1.1  mrg                   mpfr_out_str (stdout, 2, IEEE_DBL_MANT_DIG, u, MPFR_RNDN);
    421      1.1  mrg #endif
    422      1.1  mrg                   printf (" prec=%u rnd_mode=%s\n", (unsigned) prec,
    423      1.1  mrg                           mpfr_print_rnd_mode (rnd));
    424      1.1  mrg                   printf ("got      ");
    425      1.1  mrg                   mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
    426      1.1  mrg                   puts ("");
    427      1.1  mrg                   printf ("expected ");
    428      1.1  mrg                   mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
    429      1.1  mrg                   puts ("");
    430      1.1  mrg                   printf ("approx   ");
    431      1.1  mrg                   mpfr_print_binary (y);
    432      1.1  mrg                   puts ("");
    433      1.1  mrg                   exit (1);
    434      1.1  mrg                 }
    435      1.1  mrg               compare2 = mpfr_cmp (t, y);
    436      1.1  mrg               /* if rounding to nearest, cannot know the sign of t - f(x)
    437      1.1  mrg                  because of composed rounding: y = o(f(x)) and t = o(y) */
    438      1.1  mrg               if (compare * compare2 >= 0)
    439      1.1  mrg                 compare = compare + compare2;
    440      1.1  mrg               else
    441      1.1  mrg                 compare = inexact; /* cannot determine sign(t-f(x)) */
    442      1.1  mrg               if (((inexact == 0) && (compare != 0)) ||
    443      1.1  mrg                   ((inexact > 0) && (compare <= 0)) ||
    444      1.1  mrg                   ((inexact < 0) && (compare >= 0)))
    445      1.1  mrg                 {
    446      1.1  mrg                   printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
    447      1.1  mrg                           "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
    448      1.1  mrg                   printf ("x="); mpfr_print_binary (x); puts ("");
    449      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    450      1.1  mrg                   printf ("u="); mpfr_print_binary (u); puts ("");
    451      1.1  mrg #endif
    452      1.1  mrg                   printf ("y="); mpfr_print_binary (y); puts ("");
    453      1.1  mrg                   printf ("t="); mpfr_print_binary (t); puts ("");
    454      1.1  mrg                   exit (1);
    455      1.1  mrg                 }
    456      1.1  mrg             }
    457      1.1  mrg           else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
    458      1.1  mrg             {
    459      1.1  mrg               /* For developers only! */
    460      1.1  mrg               MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
    461      1.1  mrg               mpfr_nexttoinf (y);
    462      1.1  mrg               if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
    463  1.1.1.2  mrg                   && !mpfr_overflow_p () && TGENERIC_SO_TEST)
    464      1.1  mrg                 {
    465      1.1  mrg                   printf ("Possible bug! |y| is the maximum finite number "
    466      1.1  mrg                           "and has been obtained when\nrounding toward zero"
    467      1.1  mrg                           " (%s). Thus there is a very probable overflow,\n"
    468      1.1  mrg                           "but the overflow flag is not set!\n",
    469      1.1  mrg                           mpfr_print_rnd_mode (rnd));
    470      1.1  mrg                   printf ("x="); mpfr_print_binary (x); puts ("");
    471      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    472      1.1  mrg                   printf ("u="); mpfr_print_binary (u); puts ("");
    473      1.1  mrg #endif
    474      1.1  mrg                   exit (1);
    475      1.1  mrg                 }
    476      1.1  mrg             }
    477      1.1  mrg 
    478      1.1  mrg         next_n:
    479      1.1  mrg           /* In case the exponent range has been changed by
    480      1.1  mrg              tests_default_random() or for special values... */
    481      1.1  mrg           mpfr_set_emin (old_emin);
    482      1.1  mrg           mpfr_set_emax (old_emax);
    483      1.1  mrg         }
    484      1.1  mrg     }
    485      1.1  mrg 
    486      1.1  mrg #ifndef TGENERIC_NOWARNING
    487      1.1  mrg   if (3 * ctrn < 2 * ctrt)
    488      1.1  mrg     printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
    489      1.1  mrg             ctrn, ctrt);
    490      1.1  mrg #endif
    491      1.1  mrg 
    492      1.1  mrg   mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
    493      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    494      1.1  mrg   mpfr_clear (u);
    495      1.1  mrg #endif
    496      1.1  mrg }
    497      1.1  mrg 
    498      1.1  mrg #undef TEST_RANDOM_POS
    499      1.1  mrg #undef TEST_RANDOM_POS2
    500      1.1  mrg #undef TEST_RANDOM_EMIN
    501      1.1  mrg #undef TEST_RANDOM_EMAX
    502      1.1  mrg #undef RAND_FUNCTION
    503      1.1  mrg #undef TWO_ARGS
    504      1.1  mrg #undef TWO_ARGS_UI
    505      1.1  mrg #undef TEST_FUNCTION
    506      1.1  mrg #undef test_generic
    507