Home | History | Annotate | Line # | Download | only in tests
tgeneric.c revision 1.1.1.3
      1      1.1  mrg /* Generic test file for functions with one or two arguments (the second being
      2  1.1.1.3  mrg    either mpfr_t or double or unsigned long).
      3      1.1  mrg 
      4  1.1.1.3  mrg Copyright 2001-2016 Free Software Foundation, Inc.
      5  1.1.1.3  mrg Contributed by the AriC and Caramba 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.1.3  mrg /* Define TWO_ARGS for two-argument functions like mpfr_pow.
     25  1.1.1.3  mrg    Define DOUBLE_ARG1 or DOUBLE_ARG2 for function with a double operand in
     26  1.1.1.3  mrg    first or second place like sub_d or d_sub.
     27  1.1.1.3  mrg    Define ULONG_ARG1 or ULONG_ARG2 for function with an unsigned long
     28  1.1.1.3  mrg    operand in first or second place like sub_ui or ui_sub. */
     29  1.1.1.3  mrg 
     30  1.1.1.3  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) || \
     31  1.1.1.3  mrg   defined(ULONG_ARG1) || defined(ULONG_ARG2)
     32  1.1.1.3  mrg #define TWO_ARGS_ALL
     33  1.1.1.3  mrg #endif
     34      1.1  mrg 
     35      1.1  mrg #ifndef TEST_RANDOM_POS
     36      1.1  mrg /* For the random function: one number on two is negative. */
     37      1.1  mrg #define TEST_RANDOM_POS 256
     38      1.1  mrg #endif
     39      1.1  mrg 
     40      1.1  mrg #ifndef TEST_RANDOM_POS2
     41      1.1  mrg /* For the random function: one number on two is negative. */
     42      1.1  mrg #define TEST_RANDOM_POS2 256
     43      1.1  mrg #endif
     44      1.1  mrg 
     45      1.1  mrg #ifndef TEST_RANDOM_EMIN
     46      1.1  mrg #define TEST_RANDOM_EMIN -256
     47      1.1  mrg #endif
     48      1.1  mrg 
     49      1.1  mrg #ifndef TEST_RANDOM_EMAX
     50      1.1  mrg #define TEST_RANDOM_EMAX 255
     51      1.1  mrg #endif
     52      1.1  mrg 
     53  1.1.1.3  mrg #ifndef TEST_RANDOM_ALWAYS_SCALE
     54  1.1.1.3  mrg #define TEST_RANDOM_ALWAYS_SCALE 0
     55  1.1.1.3  mrg #endif
     56  1.1.1.3  mrg 
     57  1.1.1.2  mrg /* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug,
     58  1.1.1.2  mrg    then define TGENERIC_SO_TEST with an adequate test (possibly 0) to
     59  1.1.1.2  mrg    omit this particular case. */
     60  1.1.1.2  mrg #ifndef TGENERIC_SO_TEST
     61  1.1.1.2  mrg #define TGENERIC_SO_TEST 1
     62  1.1.1.2  mrg #endif
     63  1.1.1.2  mrg 
     64  1.1.1.2  mrg #define STR(F) #F
     65  1.1.1.2  mrg #define MAKE_STR(S) STR(S)
     66  1.1.1.2  mrg 
     67      1.1  mrg /* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions
     68      1.1  mrg  * with 2 arguments. See <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>.
     69      1.1  mrg  */
     70      1.1  mrg #define TGENERIC_FAIL(S, X, U)                                          \
     71      1.1  mrg   do                                                                    \
     72      1.1  mrg     {                                                                   \
     73  1.1.1.3  mrg       printf ("tgeneric: %s\nx = ", (S));                               \
     74  1.1.1.3  mrg       mpfr_dump (X);;                                                   \
     75  1.1.1.3  mrg       if ((void *) (U) != 0)                                            \
     76      1.1  mrg         {                                                               \
     77      1.1  mrg           printf ("u = ");                                              \
     78  1.1.1.3  mrg           mpfr_dump (U);                                                \
     79      1.1  mrg         }                                                               \
     80  1.1.1.3  mrg       printf ("yprec = %u, rnd_mode = %s, inexact = %d\nflags =",       \
     81  1.1.1.3  mrg               (unsigned int) yprec, mpfr_print_rnd_mode (rnd),          \
     82  1.1.1.3  mrg               compare);                                                 \
     83  1.1.1.3  mrg       flags_out (flags);                                                \
     84      1.1  mrg       exit (1);                                                         \
     85      1.1  mrg     }                                                                   \
     86      1.1  mrg   while (0)
     87      1.1  mrg 
     88  1.1.1.3  mrg #define TGENERIC_CHECK_AUX(S, EXPR, U)                          \
     89  1.1.1.3  mrg   do                                                            \
     90  1.1.1.3  mrg     if (!(EXPR))                                                \
     91  1.1.1.3  mrg       TGENERIC_FAIL (S " for " MAKE_STR(TEST_FUNCTION), x, U);  \
     92  1.1.1.2  mrg   while (0)
     93  1.1.1.2  mrg 
     94      1.1  mrg #undef TGENERIC_CHECK
     95  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
     96  1.1.1.2  mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u)
     97      1.1  mrg #else
     98  1.1.1.2  mrg #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0)
     99      1.1  mrg #endif
    100      1.1  mrg 
    101      1.1  mrg #ifdef DEBUG_TGENERIC
    102      1.1  mrg #define TGENERIC_IAUX(F,P,X,U)                                          \
    103      1.1  mrg   do                                                                    \
    104      1.1  mrg     {                                                                   \
    105      1.1  mrg       printf ("tgeneric: testing function " STR(F)                      \
    106      1.1  mrg               ", %s, target prec = %lu\nx = ",                          \
    107      1.1  mrg               mpfr_print_rnd_mode (rnd), (unsigned long) (P));          \
    108  1.1.1.3  mrg       mpfr_dump (X);                                                    \
    109  1.1.1.3  mrg       if ((void *) (U) != 0)                                            \
    110      1.1  mrg         {                                                               \
    111      1.1  mrg           printf ("u = ");                                              \
    112  1.1.1.3  mrg           mpfr_dump (U);                                                \
    113      1.1  mrg         }                                                               \
    114      1.1  mrg     }                                                                   \
    115      1.1  mrg   while (0)
    116      1.1  mrg #undef TGENERIC_INFO
    117  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    118      1.1  mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u)
    119      1.1  mrg #else
    120      1.1  mrg #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0)
    121      1.1  mrg #endif
    122  1.1.1.3  mrg #endif  /* DEBUG_TGENERIC */
    123      1.1  mrg 
    124      1.1  mrg /* For some functions (for example cos), the argument reduction is too
    125      1.1  mrg    expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX
    126      1.1  mrg    to some reasonable value before including tgeneric.c. */
    127      1.1  mrg #ifndef REDUCE_EMAX
    128      1.1  mrg #define REDUCE_EMAX mpfr_get_emax ()
    129      1.1  mrg #endif
    130      1.1  mrg 
    131      1.1  mrg static void
    132  1.1.1.2  mrg test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
    133      1.1  mrg {
    134      1.1  mrg   mpfr_prec_t prec, xprec, yprec;
    135      1.1  mrg   mpfr_t x, y, z, t, w;
    136  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    137      1.1  mrg   mpfr_t u;
    138  1.1.1.3  mrg #endif
    139  1.1.1.3  mrg #if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    140      1.1  mrg   double d;
    141      1.1  mrg #endif
    142  1.1.1.3  mrg #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
    143  1.1.1.3  mrg   unsigned long i;
    144  1.1.1.3  mrg #endif
    145      1.1  mrg   mpfr_rnd_t rnd;
    146      1.1  mrg   int inexact, compare, compare2;
    147      1.1  mrg   unsigned int n;
    148      1.1  mrg   unsigned long ctrt = 0, ctrn = 0;
    149  1.1.1.3  mrg   int test_of = 1, test_uf = 1;
    150      1.1  mrg   mpfr_exp_t old_emin, old_emax;
    151      1.1  mrg 
    152      1.1  mrg   old_emin = mpfr_get_emin ();
    153      1.1  mrg   old_emax = mpfr_get_emax ();
    154      1.1  mrg 
    155      1.1  mrg   mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
    156  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    157      1.1  mrg   mpfr_init2 (u, MPFR_PREC_MIN);
    158      1.1  mrg #endif
    159      1.1  mrg 
    160      1.1  mrg   /* generic test */
    161      1.1  mrg   for (prec = p0; prec <= p1; prec++)
    162      1.1  mrg     {
    163      1.1  mrg       mpfr_set_prec (z, prec);
    164      1.1  mrg       mpfr_set_prec (t, prec);
    165      1.1  mrg       yprec = prec + 10;
    166      1.1  mrg       mpfr_set_prec (y, yprec);
    167      1.1  mrg       mpfr_set_prec (w, yprec);
    168      1.1  mrg 
    169      1.1  mrg       /* Note: in precision p1, we test 4 special cases. */
    170  1.1.1.2  mrg       for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
    171      1.1  mrg         {
    172  1.1.1.2  mrg           int infinite_input = 0;
    173  1.1.1.3  mrg           unsigned int flags;
    174  1.1.1.3  mrg           mpfr_exp_t oemin, oemax;
    175  1.1.1.2  mrg 
    176      1.1  mrg           xprec = prec;
    177      1.1  mrg           if (randlimb () & 1)
    178      1.1  mrg             {
    179  1.1.1.3  mrg               /* In half cases, modify the precision of the inputs:
    180  1.1.1.3  mrg                  If the base precision (for the result) is small,
    181  1.1.1.3  mrg                  take a larger input precision in general, else
    182  1.1.1.3  mrg                  take a smaller precision. */
    183  1.1.1.3  mrg               xprec *= (prec < 16 ? 256.0 : 1.0) *
    184  1.1.1.3  mrg                 (double) randlimb () / MP_LIMB_T_MAX;
    185      1.1  mrg               if (xprec < MPFR_PREC_MIN)
    186      1.1  mrg                 xprec = MPFR_PREC_MIN;
    187      1.1  mrg             }
    188      1.1  mrg           mpfr_set_prec (x, xprec);
    189  1.1.1.3  mrg #if defined(TWO_ARGS)
    190      1.1  mrg           mpfr_set_prec (u, xprec);
    191      1.1  mrg #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    192      1.1  mrg           mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
    193  1.1.1.3  mrg #elif defined(ULONG_ARG1) || defined(ULONG_ARG2)
    194  1.1.1.3  mrg           mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT);
    195      1.1  mrg #endif
    196      1.1  mrg 
    197      1.1  mrg           if (n > 3 || prec < p1)
    198      1.1  mrg             {
    199      1.1  mrg #if defined(RAND_FUNCTION)
    200      1.1  mrg               RAND_FUNCTION (x);
    201      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    202      1.1  mrg               RAND_FUNCTION (u);
    203      1.1  mrg #endif
    204  1.1.1.3  mrg #else  /* ! defined(RAND_FUNCTION) */
    205      1.1  mrg               tests_default_random (x, TEST_RANDOM_POS,
    206  1.1.1.3  mrg                                     TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
    207  1.1.1.3  mrg                                     TEST_RANDOM_ALWAYS_SCALE);
    208      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    209      1.1  mrg               tests_default_random (u, TEST_RANDOM_POS2,
    210  1.1.1.3  mrg                                     TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
    211  1.1.1.3  mrg                                     TEST_RANDOM_ALWAYS_SCALE);
    212      1.1  mrg #endif
    213  1.1.1.3  mrg #endif  /* ! defined(RAND_FUNCTION) */
    214      1.1  mrg             }
    215      1.1  mrg           else
    216      1.1  mrg             {
    217      1.1  mrg               /* Special cases tested in precision p1 if n <= 3. They are
    218      1.1  mrg                  useful really in the extended exponent range. */
    219  1.1.1.2  mrg #if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
    220  1.1.1.2  mrg               goto next_n;
    221  1.1.1.2  mrg #endif
    222      1.1  mrg               set_emin (MPFR_EMIN_MIN);
    223      1.1  mrg               set_emax (MPFR_EMAX_MAX);
    224      1.1  mrg               if (n <= 1)
    225      1.1  mrg                 {
    226      1.1  mrg                   mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
    227      1.1  mrg                   mpfr_set_exp (x, mpfr_get_emin ());
    228      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    229      1.1  mrg                   mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
    230      1.1  mrg                   mpfr_set_exp (u, mpfr_get_emin ());
    231      1.1  mrg #endif
    232      1.1  mrg                 }
    233      1.1  mrg               else  /* 2 <= n <= 3 */
    234      1.1  mrg                 {
    235      1.1  mrg                   if (getenv ("MPFR_CHECK_MAX") == NULL)
    236      1.1  mrg                     goto next_n;
    237      1.1  mrg                   mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
    238      1.1  mrg                   mpfr_setmax (x, REDUCE_EMAX);
    239      1.1  mrg #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
    240      1.1  mrg                   mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
    241      1.1  mrg                   mpfr_setmax (u, mpfr_get_emax ());
    242      1.1  mrg #endif
    243      1.1  mrg                 }
    244      1.1  mrg             }
    245      1.1  mrg 
    246  1.1.1.3  mrg #if defined(ULONG_ARG1) || defined(ULONG_ARG2)
    247  1.1.1.3  mrg           i = randlimb ();
    248  1.1.1.3  mrg           inexact = mpfr_set_ui (u, i, MPFR_RNDN);
    249  1.1.1.3  mrg           MPFR_ASSERTN (inexact == 0);
    250  1.1.1.3  mrg #endif
    251  1.1.1.3  mrg 
    252  1.1.1.3  mrg           /* Exponent range for the test. */
    253  1.1.1.3  mrg           oemin = mpfr_get_emin ();
    254  1.1.1.3  mrg           oemax = mpfr_get_emax ();
    255  1.1.1.3  mrg 
    256      1.1  mrg           rnd = RND_RAND ();
    257      1.1  mrg           mpfr_clear_flags ();
    258      1.1  mrg #ifdef DEBUG_TGENERIC
    259      1.1  mrg           TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
    260      1.1  mrg #endif
    261      1.1  mrg #if defined(TWO_ARGS)
    262      1.1  mrg           compare = TEST_FUNCTION (y, x, u, rnd);
    263      1.1  mrg #elif defined(DOUBLE_ARG1)
    264      1.1  mrg           d = mpfr_get_d (u, rnd);
    265      1.1  mrg           compare = TEST_FUNCTION (y, d, x, rnd);
    266  1.1.1.2  mrg           /* d can be infinite due to overflow in mpfr_get_d */
    267  1.1.1.2  mrg           infinite_input |= DOUBLE_ISINF (d);
    268      1.1  mrg #elif defined(DOUBLE_ARG2)
    269      1.1  mrg           d = mpfr_get_d (u, rnd);
    270      1.1  mrg           compare = TEST_FUNCTION (y, x, d, rnd);
    271  1.1.1.2  mrg           /* d can be infinite due to overflow in mpfr_get_d */
    272  1.1.1.2  mrg           infinite_input |= DOUBLE_ISINF (d);
    273  1.1.1.3  mrg #elif defined(ULONG_ARG1)
    274  1.1.1.3  mrg           compare = TEST_FUNCTION (y, i, x, rnd);
    275  1.1.1.3  mrg #elif defined(ULONG_ARG2)
    276  1.1.1.3  mrg           compare = TEST_FUNCTION (y, x, i, rnd);
    277      1.1  mrg #else
    278      1.1  mrg           compare = TEST_FUNCTION (y, x, rnd);
    279      1.1  mrg #endif
    280  1.1.1.3  mrg           flags = __gmpfr_flags;
    281  1.1.1.3  mrg           if (mpfr_get_emin () != oemin ||
    282  1.1.1.3  mrg               mpfr_get_emax () != oemax)
    283  1.1.1.3  mrg             {
    284  1.1.1.3  mrg               printf ("tgeneric: the exponent range has been modified"
    285  1.1.1.3  mrg                       " by the tested function!\n");
    286  1.1.1.3  mrg               exit (1);
    287  1.1.1.3  mrg             }
    288  1.1.1.3  mrg           TGENERIC_CHECK ("bad inexact flag",
    289      1.1  mrg                           (compare != 0) ^ (mpfr_inexflag_p () == 0));
    290      1.1  mrg           ctrt++;
    291      1.1  mrg 
    292  1.1.1.3  mrg           /* Tests in a reduced exponent range. */
    293  1.1.1.3  mrg           {
    294  1.1.1.3  mrg             unsigned int oldflags = flags;
    295  1.1.1.3  mrg             mpfr_exp_t e, emin, emax;
    296  1.1.1.3  mrg 
    297  1.1.1.3  mrg             /* Determine the smallest exponent range containing the
    298  1.1.1.3  mrg                exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
    299  1.1.1.3  mrg                and output (y). */
    300  1.1.1.3  mrg             emin = MPFR_EMAX_MAX;
    301  1.1.1.3  mrg             emax = MPFR_EMIN_MIN;
    302  1.1.1.3  mrg             if (MPFR_IS_PURE_FP (x))
    303  1.1.1.3  mrg               {
    304  1.1.1.3  mrg                 e = MPFR_GET_EXP (x);
    305  1.1.1.3  mrg                 if (e < emin)
    306  1.1.1.3  mrg                   emin = e;
    307  1.1.1.3  mrg                 if (e > emax)
    308  1.1.1.3  mrg                   emax = e;
    309  1.1.1.3  mrg               }
    310      1.1  mrg #if defined(TWO_ARGS)
    311  1.1.1.3  mrg             if (MPFR_IS_PURE_FP (u))
    312  1.1.1.3  mrg               {
    313  1.1.1.3  mrg                 e = MPFR_GET_EXP (u);
    314  1.1.1.3  mrg                 if (e < emin)
    315  1.1.1.3  mrg                   emin = e;
    316  1.1.1.3  mrg                 if (e > emax)
    317  1.1.1.3  mrg                   emax = e;
    318  1.1.1.3  mrg               }
    319  1.1.1.3  mrg #endif
    320  1.1.1.3  mrg             if (MPFR_IS_PURE_FP (y))
    321  1.1.1.3  mrg               {
    322  1.1.1.3  mrg                 e = MPFR_GET_EXP (y);
    323  1.1.1.3  mrg                 if (test_of && e - 1 >= emax)
    324  1.1.1.3  mrg                   {
    325  1.1.1.3  mrg                     unsigned int ex_flags;
    326  1.1.1.3  mrg 
    327  1.1.1.3  mrg                     mpfr_set_emax (e - 1);
    328  1.1.1.3  mrg                     mpfr_clear_flags ();
    329  1.1.1.3  mrg #if defined(TWO_ARGS)
    330  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, u, rnd);
    331  1.1.1.3  mrg #elif defined(DOUBLE_ARG1)
    332  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, d, x, rnd);
    333  1.1.1.3  mrg #elif defined(DOUBLE_ARG2)
    334  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, d, rnd);
    335  1.1.1.3  mrg #elif defined(ULONG_ARG1)
    336  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, i, x, rnd);
    337  1.1.1.3  mrg #elif defined(ULONG_ARG2)
    338  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, i, rnd);
    339  1.1.1.3  mrg #else
    340  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, rnd);
    341  1.1.1.3  mrg #endif
    342  1.1.1.3  mrg                     flags = __gmpfr_flags;
    343  1.1.1.3  mrg                     mpfr_set_emax (oemax);
    344  1.1.1.3  mrg                     ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
    345  1.1.1.3  mrg                     if (flags != ex_flags)
    346  1.1.1.3  mrg                       {
    347  1.1.1.3  mrg                         printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
    348  1.1.1.3  mrg                                 ", reduced exponent range [%"
    349  1.1.1.3  mrg                                 MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
    350  1.1.1.3  mrg                                 "d] (overflow test) on:\n",
    351  1.1.1.3  mrg                                 (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
    352  1.1.1.3  mrg                         printf ("x = ");
    353  1.1.1.3  mrg                         mpfr_dump (x);
    354  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    355  1.1.1.3  mrg                         printf ("u = ");
    356  1.1.1.3  mrg                         mpfr_dump (u);
    357  1.1.1.3  mrg #endif
    358  1.1.1.3  mrg                         printf ("yprec = %u, rnd_mode = %s\n",
    359  1.1.1.3  mrg                                 (unsigned int) yprec,
    360  1.1.1.3  mrg                                 mpfr_print_rnd_mode (rnd));
    361  1.1.1.3  mrg                         printf ("Expected flags =");
    362  1.1.1.3  mrg                         flags_out (ex_flags);
    363  1.1.1.3  mrg                         printf ("     got flags =");
    364  1.1.1.3  mrg                         flags_out (flags);
    365  1.1.1.3  mrg                         printf ("inex = %d, w = ", inexact);
    366  1.1.1.3  mrg                         mpfr_dump (w);
    367  1.1.1.3  mrg                         exit (1);
    368  1.1.1.3  mrg                       }
    369  1.1.1.3  mrg                     test_of = 0;  /* Overflow is tested only once. */
    370  1.1.1.3  mrg                   }
    371  1.1.1.3  mrg                 if (test_uf && e + 1 <= emin)
    372  1.1.1.3  mrg                   {
    373  1.1.1.3  mrg                     unsigned int ex_flags;
    374  1.1.1.3  mrg 
    375  1.1.1.3  mrg                     mpfr_set_emin (e + 1);
    376  1.1.1.3  mrg                     mpfr_clear_flags ();
    377  1.1.1.3  mrg #if defined(TWO_ARGS)
    378  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, u, rnd);
    379  1.1.1.3  mrg #elif defined(DOUBLE_ARG1)
    380  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, d, x, rnd);
    381  1.1.1.3  mrg #elif defined(DOUBLE_ARG2)
    382  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, d, rnd);
    383  1.1.1.3  mrg #elif defined(ULONG_ARG1)
    384  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, i, x, rnd);
    385  1.1.1.3  mrg #elif defined(ULONG_ARG2)
    386  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, i, rnd);
    387  1.1.1.3  mrg #else
    388  1.1.1.3  mrg                     inexact = TEST_FUNCTION (w, x, rnd);
    389      1.1  mrg #endif
    390  1.1.1.3  mrg                     flags = __gmpfr_flags;
    391  1.1.1.3  mrg                     mpfr_set_emin (oemin);
    392  1.1.1.3  mrg                     ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
    393  1.1.1.3  mrg                     if (flags != ex_flags)
    394  1.1.1.3  mrg                       {
    395  1.1.1.3  mrg                         printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
    396  1.1.1.3  mrg                                 ", reduced exponent range [%"
    397  1.1.1.3  mrg                                 MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
    398  1.1.1.3  mrg                                 "d] (underflow test) on:\n",
    399  1.1.1.3  mrg                                 (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
    400  1.1.1.3  mrg                         printf ("x = ");
    401  1.1.1.3  mrg                         mpfr_dump (x);
    402  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    403  1.1.1.3  mrg                         printf ("u = ");
    404  1.1.1.3  mrg                         mpfr_dump (u);
    405  1.1.1.3  mrg #endif
    406  1.1.1.3  mrg                         printf ("yprec = %u, rnd_mode = %s\n",
    407  1.1.1.3  mrg                                 (unsigned int) yprec,
    408  1.1.1.3  mrg                                 mpfr_print_rnd_mode (rnd));
    409  1.1.1.3  mrg                         printf ("Expected flags =");
    410  1.1.1.3  mrg                         flags_out (ex_flags);
    411  1.1.1.3  mrg                         printf ("     got flags =");
    412  1.1.1.3  mrg                         flags_out (flags);
    413  1.1.1.3  mrg                         printf ("inex = %d, w = ", inexact);
    414  1.1.1.3  mrg                         mpfr_dump (w);
    415  1.1.1.3  mrg                         exit (1);
    416  1.1.1.3  mrg                       }
    417  1.1.1.3  mrg                     test_uf = 0;  /* Underflow is tested only once. */
    418  1.1.1.3  mrg                   }
    419  1.1.1.3  mrg                 if (e < emin)
    420  1.1.1.3  mrg                   emin = e;
    421  1.1.1.3  mrg                 if (e > emax)
    422  1.1.1.3  mrg                   emax = e;
    423  1.1.1.3  mrg               }
    424  1.1.1.3  mrg             if (emin > emax)
    425  1.1.1.3  mrg               emin = emax;  /* case where all values are singular */
    426  1.1.1.3  mrg             /* Consistency test in a reduced exponent range. Doing it
    427  1.1.1.3  mrg                for the first 10 samples and for prec == p1 (which has
    428  1.1.1.3  mrg                some special cases) should be sufficient. */
    429  1.1.1.3  mrg             if (ctrt <= 10 || prec == p1)
    430  1.1.1.3  mrg               {
    431  1.1.1.3  mrg                 mpfr_set_emin (emin);
    432  1.1.1.3  mrg                 mpfr_set_emax (emax);
    433  1.1.1.2  mrg #ifdef DEBUG_TGENERIC
    434  1.1.1.3  mrg                 /* Useful information in case of assertion failure. */
    435  1.1.1.3  mrg                 printf ("tgeneric: reduced exponent range [%"
    436  1.1.1.3  mrg                         MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
    437  1.1.1.3  mrg                         (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
    438  1.1.1.2  mrg #endif
    439  1.1.1.3  mrg                 mpfr_clear_flags ();
    440      1.1  mrg #if defined(TWO_ARGS)
    441  1.1.1.3  mrg                 inexact = TEST_FUNCTION (w, x, u, rnd);
    442      1.1  mrg #elif defined(DOUBLE_ARG1)
    443  1.1.1.3  mrg                 inexact = TEST_FUNCTION (w, d, x, rnd);
    444      1.1  mrg #elif defined(DOUBLE_ARG2)
    445  1.1.1.3  mrg                 inexact = TEST_FUNCTION (w, x, d, rnd);
    446  1.1.1.3  mrg #elif defined(ULONG_ARG1)
    447  1.1.1.3  mrg                 inexact = TEST_FUNCTION (w, i, x, rnd);
    448  1.1.1.3  mrg #elif defined(ULONG_ARG2)
    449  1.1.1.3  mrg                 inexact = TEST_FUNCTION (w, x, i, rnd);
    450      1.1  mrg #else
    451  1.1.1.3  mrg                 inexact = TEST_FUNCTION (w, x, rnd);
    452      1.1  mrg #endif
    453  1.1.1.3  mrg                 flags = __gmpfr_flags;
    454  1.1.1.3  mrg                 mpfr_set_emin (oemin);
    455  1.1.1.3  mrg                 mpfr_set_emax (oemax);
    456  1.1.1.3  mrg                 if (! (SAME_VAL (w, y) &&
    457  1.1.1.3  mrg                        SAME_SIGN (inexact, compare) &&
    458  1.1.1.3  mrg                        flags == oldflags))
    459  1.1.1.3  mrg                   {
    460  1.1.1.3  mrg                     printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
    461  1.1.1.3  mrg                             ", reduced exponent range [%"
    462  1.1.1.3  mrg                             MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
    463  1.1.1.3  mrg                             (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
    464  1.1.1.3  mrg                     printf ("x = ");
    465  1.1.1.3  mrg                     mpfr_dump (x);
    466  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    467  1.1.1.3  mrg                     printf ("u = ");
    468  1.1.1.3  mrg                     mpfr_dump (u);
    469  1.1.1.3  mrg #endif
    470  1.1.1.3  mrg                     printf ("yprec = %u, rnd_mode = %s\n",
    471  1.1.1.3  mrg                             (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
    472  1.1.1.3  mrg                     printf ("Expected:\n  y = ");
    473  1.1.1.3  mrg                     mpfr_dump (y);
    474  1.1.1.3  mrg                     printf ("  inex = %d, flags =", compare);
    475  1.1.1.3  mrg                     flags_out (oldflags);
    476  1.1.1.3  mrg                     printf ("Got:\n  w = ");
    477  1.1.1.3  mrg                     mpfr_dump (w);
    478  1.1.1.3  mrg                     printf ("  inex = %d, flags =", inexact);
    479  1.1.1.3  mrg                     flags_out (flags);
    480  1.1.1.3  mrg                     exit (1);
    481  1.1.1.3  mrg                   }
    482  1.1.1.3  mrg               }
    483  1.1.1.3  mrg             __gmpfr_flags = oldflags;  /* restore the flags */
    484  1.1.1.3  mrg           }
    485  1.1.1.3  mrg 
    486      1.1  mrg           if (MPFR_IS_SINGULAR (y))
    487      1.1  mrg             {
    488      1.1  mrg               if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
    489  1.1.1.3  mrg                 TGENERIC_CHECK ("bad NaN flag",
    490      1.1  mrg                                 MPFR_IS_NAN (y) && mpfr_nanflag_p ());
    491      1.1  mrg               else if (MPFR_IS_INF (y))
    492  1.1.1.2  mrg                 {
    493  1.1.1.3  mrg                   TGENERIC_CHECK ("bad overflow flag",
    494  1.1.1.2  mrg                                   (compare != 0) ^ (mpfr_overflow_p () == 0));
    495  1.1.1.3  mrg                   TGENERIC_CHECK ("bad divide-by-zero flag",
    496  1.1.1.2  mrg                                   (compare == 0 && !infinite_input) ^
    497  1.1.1.2  mrg                                   (mpfr_divby0_p () == 0));
    498  1.1.1.2  mrg                 }
    499      1.1  mrg               else if (MPFR_IS_ZERO (y))
    500  1.1.1.3  mrg                 TGENERIC_CHECK ("bad underflow flag",
    501      1.1  mrg                                 (compare != 0) ^ (mpfr_underflow_p () == 0));
    502      1.1  mrg             }
    503  1.1.1.2  mrg           else if (mpfr_divby0_p ())
    504  1.1.1.2  mrg             {
    505  1.1.1.3  mrg               TGENERIC_CHECK ("both overflow and divide-by-zero",
    506  1.1.1.2  mrg                               ! mpfr_overflow_p ());
    507  1.1.1.3  mrg               TGENERIC_CHECK ("both underflow and divide-by-zero",
    508  1.1.1.2  mrg                               ! mpfr_underflow_p ());
    509  1.1.1.3  mrg               TGENERIC_CHECK ("bad compare value (divide-by-zero)",
    510  1.1.1.2  mrg                               compare == 0);
    511  1.1.1.2  mrg             }
    512      1.1  mrg           else if (mpfr_overflow_p ())
    513      1.1  mrg             {
    514  1.1.1.3  mrg               TGENERIC_CHECK ("both underflow and overflow",
    515  1.1.1.2  mrg                               ! mpfr_underflow_p ());
    516  1.1.1.3  mrg               TGENERIC_CHECK ("bad compare value (overflow)", compare != 0);
    517      1.1  mrg               mpfr_nexttoinf (y);
    518  1.1.1.3  mrg               TGENERIC_CHECK ("should have been max MPFR number (overflow)",
    519      1.1  mrg                               MPFR_IS_INF (y));
    520      1.1  mrg             }
    521      1.1  mrg           else if (mpfr_underflow_p ())
    522      1.1  mrg             {
    523  1.1.1.3  mrg               TGENERIC_CHECK ("bad compare value (underflow)", compare != 0);
    524      1.1  mrg               mpfr_nexttozero (y);
    525  1.1.1.3  mrg               TGENERIC_CHECK ("should have been min MPFR number (underflow)",
    526      1.1  mrg                               MPFR_IS_ZERO (y));
    527      1.1  mrg             }
    528      1.1  mrg           else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
    529      1.1  mrg             {
    530      1.1  mrg               ctrn++;
    531      1.1  mrg               mpfr_set (t, y, rnd);
    532      1.1  mrg               /* Risk of failures are known when some flags are already set
    533      1.1  mrg                  before the function call. Do not set the erange flag, as
    534      1.1  mrg                  it will remain set after the function call and no checks
    535      1.1  mrg                  are performed in such a case (see the mpfr_erangeflag_p
    536      1.1  mrg                  test below). */
    537      1.1  mrg               if (randlimb () & 1)
    538      1.1  mrg                 __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
    539      1.1  mrg #ifdef DEBUG_TGENERIC
    540      1.1  mrg               TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
    541      1.1  mrg #endif
    542      1.1  mrg               /* Let's increase the precision of the inputs in a random way.
    543      1.1  mrg                  In most cases, this doesn't make any difference, but for
    544      1.1  mrg                  the mpfr_fmod bug fixed in r6230, this triggers the bug. */
    545      1.1  mrg               mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
    546      1.1  mrg                                MPFR_RNDN);
    547      1.1  mrg #if defined(TWO_ARGS)
    548      1.1  mrg               mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
    549      1.1  mrg                                MPFR_RNDN);
    550      1.1  mrg               inexact = TEST_FUNCTION (z, x, u, rnd);
    551      1.1  mrg #elif defined(DOUBLE_ARG1)
    552      1.1  mrg               inexact = TEST_FUNCTION (z, d, x, rnd);
    553      1.1  mrg #elif defined(DOUBLE_ARG2)
    554      1.1  mrg               inexact = TEST_FUNCTION (z, x, d, rnd);
    555  1.1.1.3  mrg #elif defined(ULONG_ARG1)
    556  1.1.1.3  mrg               inexact = TEST_FUNCTION (z, i, x, rnd);
    557  1.1.1.3  mrg #elif defined(ULONG_ARG2)
    558  1.1.1.3  mrg               inexact = TEST_FUNCTION (z, x, i, rnd);
    559      1.1  mrg #else
    560      1.1  mrg               inexact = TEST_FUNCTION (z, x, rnd);
    561      1.1  mrg #endif
    562      1.1  mrg               if (mpfr_erangeflag_p ())
    563      1.1  mrg                 goto next_n;
    564  1.1.1.3  mrg               if (! mpfr_equal_p (t, z))
    565      1.1  mrg                 {
    566  1.1.1.3  mrg                   printf ("tgeneric: results differ for "
    567  1.1.1.3  mrg                           MAKE_STR(TEST_FUNCTION) " on\n  x = ");
    568  1.1.1.3  mrg                   mpfr_dump (x);
    569  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    570  1.1.1.3  mrg                   printf ("  u = ");
    571  1.1.1.3  mrg                   mpfr_dump (u);
    572      1.1  mrg #endif
    573  1.1.1.3  mrg                   printf ("  prec = %u, rnd_mode = %s\n",
    574  1.1.1.3  mrg                           (unsigned int) prec, mpfr_print_rnd_mode (rnd));
    575  1.1.1.3  mrg                   printf ("Got      ");
    576  1.1.1.3  mrg                   mpfr_dump (z);
    577  1.1.1.3  mrg                   printf ("Expected ");
    578  1.1.1.3  mrg                   mpfr_dump (t);
    579  1.1.1.3  mrg                   printf ("Approx   ");
    580  1.1.1.3  mrg                   mpfr_dump (y);
    581      1.1  mrg                   exit (1);
    582      1.1  mrg                 }
    583      1.1  mrg               compare2 = mpfr_cmp (t, y);
    584      1.1  mrg               /* if rounding to nearest, cannot know the sign of t - f(x)
    585      1.1  mrg                  because of composed rounding: y = o(f(x)) and t = o(y) */
    586      1.1  mrg               if (compare * compare2 >= 0)
    587      1.1  mrg                 compare = compare + compare2;
    588      1.1  mrg               else
    589      1.1  mrg                 compare = inexact; /* cannot determine sign(t-f(x)) */
    590  1.1.1.3  mrg               if (! SAME_SIGN (inexact, compare))
    591      1.1  mrg                 {
    592      1.1  mrg                   printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
    593      1.1  mrg                           "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
    594  1.1.1.3  mrg                   printf ("x = ");
    595  1.1.1.3  mrg                   mpfr_dump (x);
    596  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    597  1.1.1.3  mrg                   printf ("u = ");
    598  1.1.1.3  mrg                   mpfr_dump (u);
    599      1.1  mrg #endif
    600  1.1.1.3  mrg                   printf ("y = ");
    601  1.1.1.3  mrg                   mpfr_dump (y);
    602  1.1.1.3  mrg                   printf ("t = ");
    603  1.1.1.3  mrg                   mpfr_dump (t);
    604      1.1  mrg                   exit (1);
    605      1.1  mrg                 }
    606      1.1  mrg             }
    607      1.1  mrg           else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
    608      1.1  mrg             {
    609      1.1  mrg               /* For developers only! */
    610      1.1  mrg               MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
    611      1.1  mrg               mpfr_nexttoinf (y);
    612      1.1  mrg               if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
    613  1.1.1.2  mrg                   && !mpfr_overflow_p () && TGENERIC_SO_TEST)
    614      1.1  mrg                 {
    615      1.1  mrg                   printf ("Possible bug! |y| is the maximum finite number "
    616      1.1  mrg                           "and has been obtained when\nrounding toward zero"
    617      1.1  mrg                           " (%s). Thus there is a very probable overflow,\n"
    618      1.1  mrg                           "but the overflow flag is not set!\n",
    619      1.1  mrg                           mpfr_print_rnd_mode (rnd));
    620  1.1.1.3  mrg                   printf ("x = ");
    621  1.1.1.3  mrg                   mpfr_dump (x);
    622  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    623  1.1.1.3  mrg                   printf ("u = ");
    624  1.1.1.3  mrg                   mpfr_dump (u);
    625      1.1  mrg #endif
    626      1.1  mrg                   exit (1);
    627      1.1  mrg                 }
    628      1.1  mrg             }
    629      1.1  mrg 
    630      1.1  mrg         next_n:
    631      1.1  mrg           /* In case the exponent range has been changed by
    632      1.1  mrg              tests_default_random() or for special values... */
    633      1.1  mrg           mpfr_set_emin (old_emin);
    634      1.1  mrg           mpfr_set_emax (old_emax);
    635      1.1  mrg         }
    636      1.1  mrg     }
    637      1.1  mrg 
    638      1.1  mrg #ifndef TGENERIC_NOWARNING
    639      1.1  mrg   if (3 * ctrn < 2 * ctrt)
    640      1.1  mrg     printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
    641      1.1  mrg             ctrn, ctrt);
    642      1.1  mrg #endif
    643      1.1  mrg 
    644      1.1  mrg   mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
    645  1.1.1.3  mrg #if defined(TWO_ARGS_ALL)
    646      1.1  mrg   mpfr_clear (u);
    647      1.1  mrg #endif
    648      1.1  mrg }
    649      1.1  mrg 
    650      1.1  mrg #undef TEST_RANDOM_POS
    651      1.1  mrg #undef TEST_RANDOM_POS2
    652      1.1  mrg #undef TEST_RANDOM_EMIN
    653      1.1  mrg #undef TEST_RANDOM_EMAX
    654  1.1.1.3  mrg #undef TEST_RANDOM_ALWAYS_SCALE
    655      1.1  mrg #undef RAND_FUNCTION
    656      1.1  mrg #undef TWO_ARGS
    657  1.1.1.3  mrg #undef TWO_ARGS_ALL
    658  1.1.1.3  mrg #undef DOUBLE_ARG1
    659  1.1.1.3  mrg #undef DOUBLE_ARG2
    660  1.1.1.3  mrg #undef ULONG_ARG1
    661  1.1.1.3  mrg #undef ULONG_ARG2
    662      1.1  mrg #undef TEST_FUNCTION
    663      1.1  mrg #undef test_generic
    664