1/* auxiliary functions for MPFR tests.
2
3Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4Contributed by the AriC and Caramel projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#ifndef __MPFR_TEST_H__
24#define __MPFR_TEST_H__
25
26#include <stdio.h>
27
28#include "mpfr-impl.h"
29
30/* generates a random long int, a random double,
31   and corresponding seed initializing */
32#define DBL_RAND() ((double) randlimb() / (double) MP_LIMB_T_MAX)
33
34#define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
35#define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */
36
37/* Generates a random rounding mode */
38#define RND_RAND() ((mpfr_rnd_t) (randlimb() % MPFR_RND_MAX))
39
40/* Generates a random sign */
41#define SIGN_RAND() ( (randlimb()%2) ? MPFR_SIGN_POS : MPFR_SIGN_NEG)
42
43/* Loop for all rounding modes */
44#define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++)
45
46/* Test whether two floating-point data have the same value,
47   seen as an element of the set of the floating-point data
48   (Level 2 in the IEEE 754-2008 standard). */
49#define SAME_VAL(X,Y)                                                   \
50  ((MPFR_IS_NAN (X) && MPFR_IS_NAN (Y)) ||                              \
51   (mpfr_equal_p ((X), (Y)) && MPFR_INT_SIGN (X) == MPFR_INT_SIGN (Y)))
52
53/* The MAX, MIN and ABS macros may already be defined if gmp-impl.h has
54   been included. They have the same semantics as in gmp-impl.h, but the
55   expressions may be slightly different. So, it's better to undefine
56   them first, as required by the ISO C standard. */
57#undef MAX
58#undef MIN
59#undef ABS
60#define MAX(a, b) (((a) > (b)) ? (a) : (b))
61#define MIN(a, b) (((a) < (b)) ? (a) : (b))
62#define ABS(x) (((x)>0) ? (x) : -(x))
63
64#define FLIST mpfr_ptr, mpfr_srcptr, mpfr_rnd_t
65
66#if defined (__cplusplus)
67extern "C" {
68#endif
69
70void test_version _MPFR_PROTO ((void));
71
72void tests_memory_start _MPFR_PROTO ((void));
73void tests_memory_end _MPFR_PROTO ((void));
74
75void tests_start_mpfr _MPFR_PROTO ((void));
76void tests_end_mpfr _MPFR_PROTO ((void));
77
78int mpfr_set_machine_rnd_mode _MPFR_PROTO ((mpfr_rnd_t));
79void mpfr_test_init _MPFR_PROTO ((void));
80mp_limb_t randlimb _MPFR_PROTO ((void));
81void randseed _MPFR_PROTO ((unsigned int));
82void mpfr_random2 _MPFR_PROTO ((mpfr_ptr, mp_size_t, mpfr_exp_t, gmp_randstate_t));
83int ulp _MPFR_PROTO ((double, double));
84double dbl _MPFR_PROTO ((double, int));
85double Ulp _MPFR_PROTO ((double));
86int Isnan _MPFR_PROTO ((double));
87void d_trace _MPFR_PROTO ((const char *, double));
88void ld_trace _MPFR_PROTO ((const char *, long double));
89
90FILE *src_fopen _MPFR_PROTO ((const char *, const char *));
91void set_emin _MPFR_PROTO ((mpfr_exp_t));
92void set_emax _MPFR_PROTO ((mpfr_exp_t));
93void tests_default_random _MPFR_PROTO ((mpfr_ptr, int, mpfr_exp_t, mpfr_exp_t));
94void data_check _MPFR_PROTO ((const char *, int (*) (FLIST), const char *));
95void bad_cases _MPFR_PROTO ((int (*)(FLIST), int (*)(FLIST),
96                             const char *, int, mpfr_exp_t, mpfr_exp_t,
97                             mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, int));
98void flags_out _MPFR_PROTO ((unsigned int));
99
100int mpfr_cmp_str _MPFR_PROTO ((mpfr_srcptr x, const char *, int, mpfr_rnd_t));
101#define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,MPFR_RNDN)
102#define mpfr_set_str1(x,s) mpfr_set_str(x,s,10,MPFR_RNDN)
103
104#define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y))
105#define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i))
106
107#if defined (__cplusplus)
108}
109#endif
110
111/* define CHECK_EXTERNAL if you want to check mpfr against another library
112   with correct rounding. You'll probably have to modify mpfr_print_raw()
113   and/or test_add() below:
114   * mpfr_print_raw() prints each number as "p m e" where p is the precision,
115     m the mantissa (as a binary integer with sign), and e the exponent.
116     The corresponding number is m*2^e. Example: "2 10 -6" represents
117     2*2^(-6) with a precision of 2 bits.
118   * test_add() outputs "b c a" on one line, for each addition a <- b + c.
119     Currently it only prints such a line for rounding to nearest, when
120     the inputs b and c are not NaN and/or Inf.
121*/
122#ifdef CHECK_EXTERNAL
123static void
124mpfr_print_raw (mpfr_srcptr x)
125{
126  printf ("%lu ", MPFR_PREC (x));
127  if (MPFR_IS_NAN (x))
128    {
129      printf ("@NaN@");
130      return;
131    }
132
133  if (MPFR_SIGN (x) < 0)
134    printf ("-");
135
136  if (MPFR_IS_INF (x))
137    printf ("@Inf@");
138  else if (MPFR_IS_ZERO (x))
139    printf ("0 0");
140  else
141    {
142      mp_limb_t *mx;
143      mpfr_prec_t px;
144      mp_size_t n;
145
146      mx = MPFR_MANT (x);
147      px = MPFR_PREC (x);
148
149      for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
150        {
151          mp_limb_t wd, t;
152
153          MPFR_ASSERTN (n >= 0);
154          wd = mx[n];
155          for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
156            {
157              printf ((wd & t) == 0 ? "0" : "1");
158              if (--px == 0)
159                {
160                  mpfr_exp_t ex;
161
162                  ex = MPFR_GET_EXP (x);
163                  MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
164                  printf (" %ld", (long) ex - (long) MPFR_PREC (x));
165                  return;
166                }
167            }
168        }
169    }
170}
171#endif
172
173#endif
174