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