(root)/
mpfr-4.2.1/
tests/
mpfr-test.h
       1  /* auxiliary functions for MPFR tests.
       2  
       3  Copyright 1999-2023 Free Software Foundation, Inc.
       4  Contributed by the AriC and Caramba projects, INRIA.
       5  
       6  This file is part of the GNU MPFR Library.
       7  
       8  The GNU MPFR Library is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU Lesser General Public License as published by
      10  the Free Software Foundation; either version 3 of the License, or (at your
      11  option) any later version.
      12  
      13  The GNU MPFR Library is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      16  License for more details.
      17  
      18  You should have received a copy of the GNU Lesser General Public License
      19  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      20  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      21  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      22  
      23  #ifndef __MPFR_TEST_H__
      24  #define __MPFR_TEST_H__
      25  
      26  /* Include config.h before using ANY configure macros if needed. */
      27  #ifdef HAVE_CONFIG_H
      28  # include "config.h"
      29  #endif
      30  
      31  /* The no assertion request doesn't apply to the tests */
      32  #if defined(MPFR_WANT_ASSERT)
      33  # if MPFR_WANT_ASSERT < 0
      34  #  undef MPFR_WANT_ASSERT
      35  # endif
      36  #endif
      37  
      38  #include "mpfr-impl.h"
      39  
      40  /* Avoid a GCC bug on Sparc, at least when using TLS. The MPFR library
      41   * itself is not affected, only a particular test. Normal code using
      42   * the MPFR library should not be affected either, as the bug occurs
      43   * when accessing __gmpfr_flags directly (and the public mpfr.h header
      44   * file does not provide any macro that accesses an internal variable
      45   * directly). So a workaround for the tests is the best solution.
      46   *
      47   * This bug, which could be observed under Debian with GCC 4.5.3 and
      48   * sparc-sun-solaris2.10 with GCC 5.5.0 when TLS and optimizations
      49   * are used[*], makes test programs using bad_cases() crash (SIGSEGV)
      50   * in this function at:
      51   *
      52   *   if (mpfr_nanflag_p () || mpfr_overflow_p () || mpfr_underflow_p ())
      53   *
      54   * Debugging shows that any attempt to access __gmpfr_flags directly
      55   * in the loop makes the program crash at this moment. This bug is not
      56   * present in the assembly code generated by -S, but is visible after a
      57   * normal compilation + link, when tracing the assembly code with gdb.
      58   * The workaround is to disable the macros from mpfr-impl.h that access
      59   * __gmpfr_flags directly. This bug may have been fixed in more recent
      60   * GCC versions, but it is safe to enable this workaround in all GCC
      61   * versions.
      62   *
      63   * [*] This is the default. Disabling TLS or recompiling the tests
      64   * without optimizations (-O0) makes the crash disappear.
      65   *
      66   * Mentions of these crashes:
      67   *   https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00045.html [Debian]
      68   *   https://sympa.inria.fr/sympa/arc/mpfr/2011-10/msg00055.html [Debian]
      69   *   https://sympa.inria.fr/sympa/arc/mpfr/2011-12/msg00000.html [Solaris 10]
      70   *   https://sympa.inria.fr/sympa/arc/mpfr/2011-12/msg00001.html [Solaris 10]
      71   *   https://sympa.inria.fr/sympa/arc/mpfr/2011-12/msg00002.html
      72   *   https://sympa.inria.fr/sympa/arc/mpfr/2016-03/msg00061.html [Solaris 10]
      73   *   https://sympa.inria.fr/sympa/arc/mpfr/2016-03/msg00063.html
      74   *   https://sympa.inria.fr/sympa/arc/mpfr/2020-06/msg00015.html [Solaris 10]
      75   *   https://sympa.inria.fr/sympa/arc/mpfr/2020-06/msg00020.html
      76   */
      77  #if defined(__GNUC__) && defined (__sparc__)
      78  # undef mpfr_underflow_p
      79  # undef mpfr_overflow_p
      80  # undef mpfr_nanflag_p
      81  # undef mpfr_inexflag_p
      82  # undef mpfr_erangeflag_p
      83  # undef mpfr_divby0_p
      84  #endif
      85  
      86  #ifdef MPFR_TESTS_ABORT
      87  # undef exit
      88  # define exit(C) ((C) != 1 ? (exit)(C) : \
      89                    (fflush (stdout), fflush (stderr), abort ()))
      90  #endif
      91  
      92  #define STRINGIZE(S) #S
      93  #define MAKE_STR(S) STRINGIZE(S)
      94  
      95  /* In C (but not C++), mpfr_ptr and mpfr_srcptr arguments can be provided
      96     in a different pointer type, such as void *. For functions implemented
      97     as macros, the type conversion for the function parameters will not be
      98     done by the compiler, which means potential bugs in these implementations
      99     if we forget to take these unusual cases into account. So we need to test
     100     such arguments, in order to make sure that the arguments are converted to
     101     the expected type when needed.
     102  
     103     However, at least when the function is not implemented as a macro (which
     104     is the case when MPFR_USE_NO_MACRO is defined), such tests with void *
     105     arguments are not valid in C++; therefore, we will not do the cast to
     106     void * if the __cplusplus macro is defined. And with GCC 4.6+ compilers
     107     (and compatible), we will ignore the -Wc++-compat option around these
     108     tests.
     109  
     110     Note: in the future, inline functions could be used instead of macros,
     111     and such tests would become useless (except to detect compiler bugs).
     112  */
     113  #if defined (__cplusplus)
     114  #define VOIDP_CAST(X) (X)
     115  #else
     116  #define VOIDP_CAST(X) ((void *) (X))
     117  /* Define IGNORE_CPP_COMPAT only for the GCC and Clang versions that
     118     support it.
     119     Note: GCC versions < 4.6 do not allow "#pragma GCC diagnostic" inside
     120     functions, and Clang on Windows (clang-cl) does not define __GNUC__.
     121     See https://sympa.inria.fr/sympa/arc/mpfr/2022-12/msg00007.html */
     122  #if __MPFR_GNUC(4,6) || defined (__clang__)
     123  #define IGNORE_CPP_COMPAT
     124  #endif
     125  #endif
     126  
     127  #if defined (__cplusplus)
     128  extern "C" {
     129  #endif
     130  
     131  /* generates a random long int, a random double,
     132     and corresponding seed initializing */
     133  #define DBL_RAND() ((double) randlimb() / (double) MPFR_LIMB_MAX)
     134  
     135  #define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
     136  #define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */
     137  
     138  /* Generates a random rounding mode */
     139  #define RND_RAND() ((mpfr_rnd_t) (randlimb() % MPFR_RND_MAX))
     140  
     141  /* Ditto, excluding RNDF, assumed to be the last rounding mode */
     142  #define RND_RAND_NO_RNDF() ((mpfr_rnd_t) (randlimb() % MPFR_RNDF))
     143  
     144  /* Generates a random boolean (with type int, thanks to the "!= 0" test).
     145     Note: "& 1" is better than "% 2" for compilers with limited optimization,
     146     such as tcc 0.9.27. */
     147  #define RAND_BOOL() ((randlimb() & 1) != 0)
     148  
     149  /* Generates a random sign */
     150  #define RAND_SIGN() (RAND_BOOL() ? MPFR_SIGN_POS : MPFR_SIGN_NEG)
     151  
     152  /* Loop for all rounding modes */
     153  #define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++)
     154  
     155  /* Loop for all rounding modes except RNDF (assumed to be the last one),
     156     which must be excluded from tests that rely on deterministic results. */
     157  #define RND_LOOP_NO_RNDF(_r) for((_r) = 0 ; (_r) < MPFR_RNDF ; (_r)++)
     158  
     159  /* Test whether two floating-point data have the same value,
     160     seen as an element of the set of the floating-point data
     161     (Level 2 in the IEEE 754-2008 standard). */
     162  #define SAME_VAL(X,Y)                                                   \
     163    ((MPFR_IS_NAN (X) && MPFR_IS_NAN (Y)) ||                              \
     164     (mpfr_equal_p ((X), (Y)) && MPFR_INT_SIGN (X) == MPFR_INT_SIGN (Y)))
     165  
     166  /* In the tests, mpfr_sgn was sometimes used incorrectly, for instance:
     167   *
     168   *   if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
     169   *
     170   * to check that y is +0. This does not make sense since on 0, mpfr_sgn
     171   * yields 0, so that -0 would not be detected as an error. To make sure
     172   * that mpfr_sgn is not used incorrectly, we choose to fail when this
     173   * macro is used on a datum whose mathematical sign is not +1 or -1.
     174   * This feature is disabled when MPFR_TESTS_TSGN is defined, typically
     175   * in tsgn (to test mpfr_sgn itself).
     176   */
     177  #ifndef MPFR_TESTS_TSGN
     178  # undef mpfr_sgn
     179  # define mpfr_sgn(x)                   \
     180    (MPFR_ASSERTN (! MPFR_IS_NAN (x)),   \
     181     MPFR_ASSERTN (! MPFR_IS_ZERO (x)),  \
     182     MPFR_SIGN (x))
     183  #endif
     184  
     185  #define FLIST mpfr_ptr, mpfr_srcptr, mpfr_rnd_t
     186  
     187  int test_version (void);
     188  
     189  /* Memory handling */
     190  #define DEFAULT_MEMORY_LIMIT (1UL << 22)
     191  extern size_t tests_memory_limit;
     192  void tests_memory_start (void);
     193  void tests_memory_end (void);
     194  
     195  void tests_start_mpfr (void);
     196  void tests_end_mpfr (void);
     197  
     198  void tests_expect_abort (void);
     199  int tests_run_within_valgrind (void);
     200  
     201  int mpfr_set_machine_rnd_mode (mpfr_rnd_t);
     202  int have_subnorm_dbl (void);
     203  int have_subnorm_flt (void);
     204  void mpfr_test_init (void);
     205  mp_limb_t randlimb (void);
     206  unsigned long randulong (void);
     207  long randlong (void);
     208  void randseed (unsigned int);
     209  void mpfr_random2 (mpfr_ptr, mp_size_t, mpfr_exp_t, gmp_randstate_t);
     210  int ulp (double, double);
     211  double dbl (double, int);
     212  double Ulp (double);
     213  int Isnan (double);
     214  void d_trace (const char *, double);
     215  void ld_trace (const char *, long double);
     216  void n_trace (const char *, mp_limb_t *, mp_size_t);
     217  
     218  FILE *src_fopen (const char *, const char *);
     219  void set_emin (mpfr_exp_t);
     220  void set_emax (mpfr_exp_t);
     221  void tests_default_random (mpfr_ptr, int, mpfr_exp_t, mpfr_exp_t,
     222                             int);
     223  void data_check (const char *, int (*) (FLIST), const char *);
     224  void bad_cases (int (*)(FLIST), int (*)(FLIST),
     225                  const char *, int, mpfr_exp_t, mpfr_exp_t,
     226                  mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, int);
     227  void flags_out (unsigned int);
     228  
     229  int mpfr_cmp_str (mpfr_srcptr x, const char *, int, mpfr_rnd_t);
     230  #define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,MPFR_RNDN)
     231  #define mpfr_set_str1(x,s) mpfr_set_str(x,s,10,MPFR_RNDN)
     232  
     233  #define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y))
     234  #define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i))
     235  #define mpfr_cmp_si0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_si (x,i))
     236  #define mpfr_cmp_si_2exp0(x,i,e) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), \
     237                                    mpfr_cmp_si_2exp (x,i,e))
     238  
     239  /* define CHECK_EXTERNAL if you want to check mpfr against another library
     240     with correct rounding. You'll probably have to modify mpfr_print_raw()
     241     and/or test_add() below:
     242     * mpfr_print_raw() prints each number as "p m e" where p is the precision,
     243       m the mantissa (as a binary integer with sign), and e the exponent.
     244       The corresponding number is m*2^e. Example: "2 10 -6" represents
     245       2*2^(-6) with a precision of 2 bits.
     246     * test_add() outputs "b c a" on one line, for each addition a <- b + c.
     247       Currently it only prints such a line for rounding to nearest, when
     248       the inputs b and c are not NaN and/or Inf.
     249  */
     250  #ifdef CHECK_EXTERNAL
     251  static void
     252  mpfr_print_raw (mpfr_srcptr x)
     253  {
     254    printf ("%lu ", MPFR_PREC (x));
     255    if (MPFR_IS_NAN (x))
     256      {
     257        printf ("@NaN@");
     258        return;
     259      }
     260  
     261    if (MPFR_IS_NEG (x))
     262      printf ("-");
     263  
     264    if (MPFR_IS_INF (x))
     265      printf ("@Inf@");
     266    else if (MPFR_IS_ZERO (x))
     267      printf ("0 0");
     268    else
     269      {
     270        mp_limb_t *mx;
     271        mpfr_prec_t px;
     272        mp_size_t n;
     273  
     274        mx = MPFR_MANT (x);
     275        px = MPFR_PREC (x);
     276  
     277        for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
     278          {
     279            mp_limb_t wd, t;
     280  
     281            MPFR_ASSERTN (n >= 0);
     282            wd = mx[n];
     283            for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
     284              {
     285                printf ((wd & t) == 0 ? "0" : "1");
     286                if (--px == 0)
     287                  {
     288                    mpfr_exp_t ex;
     289  
     290                    ex = MPFR_GET_EXP (x);
     291                    MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
     292                    printf (" %ld", (long) ex - (long) MPFR_PREC (x));
     293                    return;
     294                  }
     295              }
     296          }
     297      }
     298  }
     299  #endif
     300  
     301  extern char *locale;
     302  
     303  /* Random */
     304  extern char             mpfr_rands_initialized;
     305  extern gmp_randstate_t  mpfr_rands;
     306  
     307  #undef RANDS
     308  #define RANDS                                   \
     309    ((mpfr_rands_initialized ? 0                 \
     310      : (mpfr_rands_initialized = 1,             \
     311         gmp_randinit_default (mpfr_rands), 0)), \
     312     mpfr_rands)
     313  
     314  #undef RANDS_CLEAR
     315  #define RANDS_CLEAR()                   \
     316    do {                                  \
     317      if (mpfr_rands_initialized)        \
     318        {                                 \
     319          mpfr_rands_initialized = 0;    \
     320          gmp_randclear (mpfr_rands);    \
     321        }                                 \
     322    } while (0)
     323  
     324  /* Memory Allocation */
     325  extern int tests_memory_disabled;
     326  void *tests_allocate (size_t);
     327  void *tests_reallocate (void *, size_t, size_t);
     328  void tests_free (void *, size_t);
     329  
     330  #if defined (__cplusplus)
     331  }
     332  #endif
     333  
     334  /* With GCC, a macro "volatile" can be defined to test some special code
     335     in mpfr-impl.h (code for compilers that define such a macro), but the
     336     volatile keyword is necessary in some tests to avoid some GCC bugs.
     337     Thus we need to undef this macro (if defined). We do that at the end,
     338     so that mpfr-impl.h (included earlier) is not affected by this undef.
     339   */
     340  #if defined(__GNUC__) && defined(volatile)
     341  # undef volatile
     342  #endif
     343  
     344  #endif