summaryrefslogtreecommitdiff
path: root/tests/mpfr-test.h
blob: 5e67905af5e8aaf0be1877aa09d94bcbefcf2d9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/* auxiliary functions for MPFR tests.

Copyright 1999-2015 Free Software Foundation, Inc.
Contributed by the AriC and Caramel projects, INRIA.

This file is part of the GNU MPFR Library.

The GNU MPFR Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

The GNU MPFR Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */

#ifndef __MPFR_TEST_H__
#define __MPFR_TEST_H__

/* Include config.h before using ANY configure macros if needed. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

/* The no assertion request doesn't apply to the tests */
#if defined(MPFR_WANT_ASSERT)
# if MPFR_WANT_ASSERT < 0
#  undef MPFR_WANT_ASSERT
# endif
#endif

#include "mpfr-impl.h"

#if defined (__cplusplus)
extern "C" {
#endif

/* generates a random long int, a random double,
   and corresponding seed initializing */
#define DBL_RAND() ((double) randlimb() / (double) MPFR_LIMB_MAX)

#define MINNORM 2.2250738585072013831e-308 /* 2^(-1022), smallest normalized */
#define MAXNORM 1.7976931348623157081e308 /* 2^(1023)*(2-2^(-52)) */

/* Generates a random rounding mode */
#define RND_RAND() ((mpfr_rnd_t) (randlimb() % MPFR_RND_MAX))

/* Generates a random sign */
#define SIGN_RAND() ( (randlimb()%2) ? MPFR_SIGN_POS : MPFR_SIGN_NEG)

/* Loop for all rounding modes */
#define RND_LOOP(_r) for((_r) = 0 ; (_r) < MPFR_RND_MAX ; (_r)++)

/* Test whether two floating-point data have the same value,
   seen as an element of the set of the floating-point data
   (Level 2 in the IEEE 754-2008 standard). */
#define SAME_VAL(X,Y)                                                   \
  ((MPFR_IS_NAN (X) && MPFR_IS_NAN (Y)) ||                              \
   (mpfr_equal_p ((X), (Y)) && MPFR_INT_SIGN (X) == MPFR_INT_SIGN (Y)))

/* The MAX, MIN and ABS macros may already be defined if gmp-impl.h has
   been included. They have the same semantics as in gmp-impl.h, but the
   expressions may be slightly different. So, it's better to undefine
   them first, as required by the ISO C standard. */
#undef MAX
#undef MIN
#undef ABS
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define ABS(x) (((x)>0) ? (x) : -(x))

#define FLIST mpfr_ptr, mpfr_srcptr, mpfr_rnd_t

int test_version _MPFR_PROTO ((void));

void tests_memory_start _MPFR_PROTO ((void));
void tests_memory_end _MPFR_PROTO ((void));

void tests_start_mpfr _MPFR_PROTO ((void));
void tests_end_mpfr _MPFR_PROTO ((void));

void tests_expect_abort _MPFR_PROTO ((void));

int mpfr_set_machine_rnd_mode _MPFR_PROTO ((mpfr_rnd_t));
void mpfr_test_init _MPFR_PROTO ((void));
mp_limb_t randlimb _MPFR_PROTO ((void));
void randseed _MPFR_PROTO ((unsigned int));
void mpfr_random2 _MPFR_PROTO ((mpfr_ptr, mp_size_t, mpfr_exp_t, gmp_randstate_t));
int ulp _MPFR_PROTO ((double, double));
double dbl _MPFR_PROTO ((double, int));
double Ulp _MPFR_PROTO ((double));
int Isnan _MPFR_PROTO ((double));
void d_trace _MPFR_PROTO ((const char *, double));
void ld_trace _MPFR_PROTO ((const char *, long double));

FILE *src_fopen _MPFR_PROTO ((const char *, const char *));
void set_emin _MPFR_PROTO ((mpfr_exp_t));
void set_emax _MPFR_PROTO ((mpfr_exp_t));
void tests_default_random _MPFR_PROTO ((mpfr_ptr, int, mpfr_exp_t, mpfr_exp_t,
                                        int));
void data_check _MPFR_PROTO ((const char *, int (*) (FLIST), const char *));
void bad_cases _MPFR_PROTO ((int (*)(FLIST), int (*)(FLIST),
                             const char *, int, mpfr_exp_t, mpfr_exp_t,
                             mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, int));
void flags_out _MPFR_PROTO ((unsigned int));

int mpfr_cmp_str _MPFR_PROTO ((mpfr_srcptr x, const char *, int, mpfr_rnd_t));
#define mpfr_cmp_str1(x,s) mpfr_cmp_str(x,s,10,MPFR_RNDN)
#define mpfr_set_str1(x,s) mpfr_set_str(x,s,10,MPFR_RNDN)

#define mpfr_cmp0(x,y) (MPFR_ASSERTN (!MPFR_IS_NAN (x) && !MPFR_IS_NAN (y)), mpfr_cmp (x,y))
#define mpfr_cmp_ui0(x,i) (MPFR_ASSERTN (!MPFR_IS_NAN (x)), mpfr_cmp_ui (x,i))

/* define CHECK_EXTERNAL if you want to check mpfr against another library
   with correct rounding. You'll probably have to modify mpfr_print_raw()
   and/or test_add() below:
   * mpfr_print_raw() prints each number as "p m e" where p is the precision,
     m the mantissa (as a binary integer with sign), and e the exponent.
     The corresponding number is m*2^e. Example: "2 10 -6" represents
     2*2^(-6) with a precision of 2 bits.
   * test_add() outputs "b c a" on one line, for each addition a <- b + c.
     Currently it only prints such a line for rounding to nearest, when
     the inputs b and c are not NaN and/or Inf.
*/
#ifdef CHECK_EXTERNAL
static void
mpfr_print_raw (mpfr_srcptr x)
{
  printf ("%lu ", MPFR_PREC (x));
  if (MPFR_IS_NAN (x))
    {
      printf ("@NaN@");
      return;
    }

  if (MPFR_IS_NEG (x))
    printf ("-");

  if (MPFR_IS_INF (x))
    printf ("@Inf@");
  else if (MPFR_IS_ZERO (x))
    printf ("0 0");
  else
    {
      mp_limb_t *mx;
      mpfr_prec_t px;
      mp_size_t n;

      mx = MPFR_MANT (x);
      px = MPFR_PREC (x);

      for (n = (px - 1) / GMP_NUMB_BITS; ; n--)
        {
          mp_limb_t wd, t;

          MPFR_ASSERTN (n >= 0);
          wd = mx[n];
          for (t = MPFR_LIMB_HIGHBIT; t != 0; t >>= 1)
            {
              printf ((wd & t) == 0 ? "0" : "1");
              if (--px == 0)
                {
                  mpfr_exp_t ex;

                  ex = MPFR_GET_EXP (x);
                  MPFR_ASSERTN (ex >= LONG_MIN && ex <= LONG_MAX);
                  printf (" %ld", (long) ex - (long) MPFR_PREC (x));
                  return;
                }
            }
        }
    }
}
#endif

/* Random */
__MPFR_DECLSPEC extern char             mpfr_rands_initialized;
__MPFR_DECLSPEC extern gmp_randstate_t  mpfr_rands;

#undef RANDS
#define RANDS                                   \
  ((mpfr_rands_initialized ? 0                 \
    : (mpfr_rands_initialized = 1,             \
       gmp_randinit_default (mpfr_rands), 0)), \
   mpfr_rands)

#undef RANDS_CLEAR
#define RANDS_CLEAR()                   \
  do {                                  \
    if (mpfr_rands_initialized)        \
      {                                 \
        mpfr_rands_initialized = 0;    \
        gmp_randclear (mpfr_rands);    \
      }                                 \
  } while (0)

typedef __gmp_randstate_struct *mpfr_gmp_randstate_ptr;

/* Allocation */
__MPFR_DECLSPEC void *mpfr_default_allocate _MPFR_PROTO ((size_t));
__MPFR_DECLSPEC void *mpfr_default_reallocate _MPFR_PROTO ((void *, size_t,
                                                             size_t));
__MPFR_DECLSPEC void mpfr_default_free _MPFR_PROTO ((void *, size_t));


#if defined (__cplusplus)
}
#endif

#endif