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