1 /* auxiliary functions for MPFR tests.
2 
3 Copyright 1999-2020 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 compilers (and
107    compatible), we will ignore the -Wc++-compat option around these tests.
108 
109    Note: in the future, inline functions could be used instead of macros,
110    and such tests would become useless (except to detect compiler bugs).
111 */
112 #if defined (__cplusplus)
113 #define VOIDP_CAST(X) (X)
114 #else
115 #define VOIDP_CAST(X) ((void *) (X))
116 #if defined (__GNUC__)
117 #define IGNORE_CPP_COMPAT
118 #endif
119 #endif
120 
121 #if defined (__cplusplus)
122 extern "C" {
123 #endif
124 
125 /* generates a random long int, a random double,
126    and corresponding seed initializing */
127 #define DBL_RAND() ((double) randlimb() / (double) MPFR_LIMB_MAX)
128 
129 #define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
130 #define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */
131 
132 /* Generates a random rounding mode */
133 #define RND_RAND() ((mpfr_rnd_t) (randlimb() % MPFR_RND_MAX))
134 
135 /* Ditto, excluding RNDF, assumed to be the last rounding mode */
136 #define RND_RAND_NO_RNDF() ((mpfr_rnd_t) (randlimb() % MPFR_RNDF))
137 
138 /* Generates a random sign */
139 #define RAND_SIGN() (randlimb() % 2 ? MPFR_SIGN_POS : MPFR_SIGN_NEG)
140 
141 /* Loop for all rounding modes */
142 #define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++)
143 
144 /* Loop for all rounding modes except RNDF (assumed to be the last one),
145    which must be excluded from tests that rely on deterministic results. */
146 #define RND_LOOP_NO_RNDF(_r) for((_r) = 0 ; (_r) < MPFR_RNDF ; (_r)++)
147 
148 /* Test whether two floating-point data have the same value,
149    seen as an element of the set of the floating-point data
150    (Level 2 in the IEEE 754-2008 standard). */
151 #define SAME_VAL(X,Y)                                                   \
152   ((MPFR_IS_NAN (X) && MPFR_IS_NAN (Y)) ||                              \
153    (mpfr_equal_p ((X), (Y)) && MPFR_INT_SIGN (X) == MPFR_INT_SIGN (Y)))
154 
155 /* In the tests, mpfr_sgn was sometimes used incorrectly, for instance:
156  *
157  *   if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
158  *
159  * to check that y is +0. This does not make sense since on 0, mpfr_sgn
160  * yields 0, so that -0 would not be detected as an error. To make sure
161  * that mpfr_sgn is not used incorrectly, we choose to fail when this
162  * macro is used on a datum whose mathematical sign is not +1 or -1.
163  * This feature is disabled when MPFR_TESTS_TSGN is defined, typically
164  * in tsgn (to test mpfr_sgn itself).
165  */
166 #ifndef MPFR_TESTS_TSGN
167 # undef mpfr_sgn
168 # define mpfr_sgn(x)                   \
169   (MPFR_ASSERTN (! MPFR_IS_NAN (x)),   \
170    MPFR_ASSERTN (! MPFR_IS_ZERO (x)),  \
171    MPFR_SIGN (x))
172 #endif
173 
174 #define FLIST mpfr_ptr, mpfr_srcptr, mpfr_rnd_t
175 
176 int test_version (void);
177 
178 /* Memory handling */
179 #define DEFAULT_MEMORY_LIMIT (1UL << 22)
180 extern size_t tests_memory_limit;
181 void tests_memory_start (void);
182 void tests_memory_end (void);
183 
184 void tests_start_mpfr (void);
185 void tests_end_mpfr (void);
186 
187 void tests_expect_abort (void);
188 int tests_run_within_valgrind (void);
189 
190 int mpfr_set_machine_rnd_mode (mpfr_rnd_t);
191 void mpfr_test_init (void);
192 mp_limb_t randlimb (void);
193 void randseed (unsigned int);
194 void mpfr_random2 (mpfr_ptr, mp_size_t, mpfr_exp_t, gmp_randstate_t);
195 int ulp (double, double);
196 double dbl (double, int);
197 double Ulp (double);
198 int Isnan (double);
199 void d_trace (const char *, double);
200 void ld_trace (const char *, long double);
201 void n_trace (const char *, mp_limb_t *, mp_size_t);
202 
203 FILE *src_fopen (const char *, const char *);
204 void set_emin (mpfr_exp_t);
205 void set_emax (mpfr_exp_t);
206 void tests_default_random (mpfr_ptr, int, mpfr_exp_t, mpfr_exp_t,
207                            int);
208 void data_check (const char *, int (*) (FLIST), const char *);
209 void bad_cases (int (*)(FLIST), int (*)(FLIST),
210                 const char *, int, mpfr_exp_t, mpfr_exp_t,
211                 mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, int);
212 void flags_out (unsigned int);
213 
214 int mpfr_cmp_str (mpfr_srcptr x, const char *, int, mpfr_rnd_t);
215 #define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,MPFR_RNDN)
216 #define mpfr_set_str1(x,s) mpfr_set_str(x,s,10,MPFR_RNDN)
217 
218 #define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y))
219 #define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i))
220 #define mpfr_cmp_si_2exp0(x,i,e) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), \
221                                   mpfr_cmp_si_2exp (x,i,e))
222 
223 /* define CHECK_EXTERNAL if you want to check mpfr against another library
224    with correct rounding. You'll probably have to modify mpfr_print_raw()
225    and/or test_add() below:
226    * mpfr_print_raw() prints each number as "p m e" where p is the precision,
227      m the mantissa (as a binary integer with sign), and e the exponent.
228      The corresponding number is m*2^e. Example: "2 10 -6" represents
229      2*2^(-6) with a precision of 2 bits.
230    * test_add() outputs "b c a" on one line, for each addition a <- b + c.
231      Currently it only prints such a line for rounding to nearest, when
232      the inputs b and c are not NaN and/or Inf.
233 */
234 #ifdef CHECK_EXTERNAL
235 static void
mpfr_print_raw(mpfr_srcptr x)236 mpfr_print_raw (mpfr_srcptr x)
237 {
238   printf ("%lu ", MPFR_PREC (x));
239   if (MPFR_IS_NAN (x))
240     {
241       printf ("@NaN@");
242       return;
243     }
244 
245   if (MPFR_IS_NEG (x))
246     printf ("-");
247 
248   if (MPFR_IS_INF (x))
249     printf ("@Inf@");
250   else if (MPFR_IS_ZERO (x))
251     printf ("0 0");
252   else
253     {
254       mp_limb_t *mx;
255       mpfr_prec_t px;
256       mp_size_t n;
257 
258       mx = MPFR_MANT (x);
259       px = MPFR_PREC (x);
260 
261       for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
262         {
263           mp_limb_t wd, t;
264 
265           MPFR_ASSERTN (n >= 0);
266           wd = mx[n];
267           for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
268             {
269               printf ((wd & t) == 0 ? "0" : "1");
270               if (--px == 0)
271                 {
272                   mpfr_exp_t ex;
273 
274                   ex = MPFR_GET_EXP (x);
275                   MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
276                   printf (" %ld", (long) ex - (long) MPFR_PREC (x));
277                   return;
278                 }
279             }
280         }
281     }
282 }
283 #endif
284 
285 extern char *locale;
286 
287 /* Random */
288 extern char             mpfr_rands_initialized;
289 extern gmp_randstate_t  mpfr_rands;
290 
291 #undef RANDS
292 #define RANDS                                   \
293   ((mpfr_rands_initialized ? 0                 \
294     : (mpfr_rands_initialized = 1,             \
295        gmp_randinit_default (mpfr_rands), 0)), \
296    mpfr_rands)
297 
298 #undef RANDS_CLEAR
299 #define RANDS_CLEAR()                   \
300   do {                                  \
301     if (mpfr_rands_initialized)        \
302       {                                 \
303         mpfr_rands_initialized = 0;    \
304         gmp_randclear (mpfr_rands);    \
305       }                                 \
306   } while (0)
307 
308 /* Memory Allocation */
309 extern int tests_memory_disabled;
310 void *tests_allocate (size_t);
311 void *tests_reallocate (void *, size_t, size_t);
312 void tests_free (void *, size_t);
313 
314 #if defined (__cplusplus)
315 }
316 #endif
317 
318 /* With GCC, a macro "volatile" can be defined to test some special code
319    in mpfr-impl.h (code for compilers that define such a macro), but the
320    volatile keyword is necessary in some tests to avoid some GCC bugs.
321    Thus we need to undef this macro (if defined). We do that at the end,
322    so that mpfr-impl.h (included earlier) is not affected by this undef.
323  */
324 #if defined(__GNUC__) && defined(volatile)
325 # undef volatile
326 #endif
327 
328 #endif
329