1 /* Test file for
2 mpfr_set_sj, mpfr_set_uj, mpfr_set_sj_2exp and mpfr_set_uj_2exp.
3
4 Copyright 2004, 2006-2020 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6
7 This file is part of the GNU MPFR Library.
8
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24 #define MPFR_NEED_INTMAX_H
25 #include "mpfr-test.h"
26
27 #ifndef _MPFR_H_HAVE_INTMAX_T
28
29 int
main(void)30 main (void)
31 {
32 return 77;
33 }
34
35 #else
36
37 #define PRINT_ERROR(str) \
38 do { printf ("Error for %s\n", str); exit (1); } while (0)
39
40 static int
inexact_sign(int x)41 inexact_sign (int x)
42 {
43 return (x < 0) ? -1 : (x > 0);
44 }
45
46 static void
check_set_uj(mpfr_prec_t pmin,mpfr_prec_t pmax,int N)47 check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N)
48 {
49 mpfr_t x, y;
50 mpfr_prec_t p;
51 int inex1, inex2, n;
52 mp_limb_t limb;
53
54 mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0);
55
56 for (p = pmin ; p < pmax ; p++)
57 {
58 mpfr_set_prec (x, p);
59 mpfr_set_prec (y, p);
60 for (n = 0 ; n < N ; n++)
61 {
62 /* mp_limb_t may be unsigned long long */
63 limb = (unsigned long) randlimb ();
64 inex1 = mpfr_set_uj (x, limb, MPFR_RNDN);
65 inex2 = mpfr_set_ui (y, limb, MPFR_RNDN);
66 if (mpfr_cmp (x, y))
67 {
68 printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n",
69 (unsigned long) limb, (unsigned long) p);
70 printf ("X="); mpfr_dump (x);
71 printf ("Y="); mpfr_dump (y);
72 exit (1);
73 }
74 if (inexact_sign (inex1) != inexact_sign (inex2))
75 {
76 printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n"
77 "Inexact1= %d Inexact2= %d\n",
78 (unsigned long) limb, (unsigned long) p, inex1, inex2);
79 exit (1);
80 }
81 }
82 }
83 /* Special case */
84 mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT);
85 inex1 = mpfr_set_uj (x, UINTMAX_MAX, MPFR_RNDN);
86 if (inex1 != 0 || mpfr_sgn(x) <= 0)
87 PRINT_ERROR ("inexact / UINTMAX_MAX");
88 inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN);
89 if (inex1 != 0 || !mpfr_powerof2_raw (x)
90 || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
91 PRINT_ERROR ("power of 2");
92 mpfr_set_uj (x, 0, MPFR_RNDN);
93 if (!MPFR_IS_ZERO (x))
94 PRINT_ERROR ("Setting 0");
95
96 mpfr_clears (x, y, (mpfr_ptr) 0);
97 }
98
99 static void
check_set_uj_2exp(void)100 check_set_uj_2exp (void)
101 {
102 mpfr_t x;
103 int inex;
104
105 mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);
106
107 inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN);
108 if (inex || mpfr_cmp_ui(x, 1))
109 PRINT_ERROR ("(1U,0)");
110
111 inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN);
112 if (inex || mpfr_cmp_ui(x, 1))
113 PRINT_ERROR ("(1024U,-10)");
114
115 inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN);
116 if (inex || mpfr_cmp_ui(x, 1024L * 1024L))
117 PRINT_ERROR ("(1024U,+10)");
118
119 inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, 1000, MPFR_RNDN);
120 inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN);
121 inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN);
122 if (inex || !mpfr_powerof2_raw (x)
123 || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
124 PRINT_ERROR ("(UINTMAX_MAX)");
125
126 inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN);
127 if (inex == 0 || !mpfr_inf_p (x))
128 PRINT_ERROR ("Overflow");
129
130 inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN);
131 if (inex == 0 || !MPFR_IS_ZERO (x))
132 PRINT_ERROR ("Underflow");
133
134 mpfr_clear (x);
135 }
136
137 static void
check_set_sj(void)138 check_set_sj (void)
139 {
140 mpfr_t x;
141 int inex;
142
143 mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
144
145 inex = mpfr_set_sj (x, -INTMAX_MAX, MPFR_RNDN);
146 inex |= mpfr_add_si (x, x, -1, MPFR_RNDN);
147 if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
148 || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT)
149 PRINT_ERROR ("set_sj (-INTMAX_MAX)");
150
151 inex = mpfr_set_sj (x, 1742, MPFR_RNDN);
152 if (inex || mpfr_cmp_ui (x, 1742))
153 PRINT_ERROR ("set_sj (1742)");
154
155 mpfr_clear (x);
156 }
157
158 static void
check_set_sj_2exp(void)159 check_set_sj_2exp (void)
160 {
161 mpfr_t x;
162 int inex;
163
164 mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
165
166 inex = mpfr_set_sj_2exp (x, INTMAX_MIN, 1000, MPFR_RNDN);
167 if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
168 || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT + 1000)
169 PRINT_ERROR ("set_sj_2exp (INTMAX_MIN)");
170
171 mpfr_clear (x);
172 }
173
174 #define REXP 1024
175
176 static void
test_2exp_extreme_aux(void)177 test_2exp_extreme_aux (void)
178 {
179 mpfr_t x1, x2, y;
180 mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
181 { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
182 mpfr_flags_t flags1, flags2;
183 int i, j, rnd, inex1, inex2;
184 char s;
185
186 ep[0] = MPFR_EXP_MIN;
187 for (i = 0; i < numberof(eb); i++)
188 for (j = 0; j < 8; j++)
189 ep[1 + 8 * i + j] = eb[i] - j;
190
191 mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
192 mpfr_init2 (y, 32);
193
194 /* The cast to int is needed if numberof(ep) is of unsigned type, in
195 which case the condition without the cast would be always false. */
196 for (i = -2; i < (int) numberof(ep); i++)
197 for (j = -31; j <= 31; j++)
198 RND_LOOP_NO_RNDF (rnd)
199 {
200 int sign = j < 0 ? -1 : 1;
201 intmax_t em;
202
203 if (i < 0)
204 {
205 em = i == -2 ? INTMAX_MIN : INTMAX_MAX;
206 mpfr_clear_flags ();
207 inex1 = j == 0 ?
208 (mpfr_set_zero (x1, +1), 0) : i == -2 ?
209 mpfr_underflow (x1, rnd == MPFR_RNDN ?
210 MPFR_RNDZ : (mpfr_rnd_t) rnd, sign) :
211 mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
212 flags1 = __gmpfr_flags;
213 }
214 else
215 {
216 em = ep[i];
217 /* Compute the expected value, inex and flags */
218 inex1 = mpfr_set_si (y, j, MPFR_RNDN);
219 MPFR_ASSERTN (inex1 == 0);
220 inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
221 /* x1 is the rounded value and inex1 the ternary value,
222 assuming that the exponent argument is 0 (this is the
223 rounded significand of the final result, assuming an
224 unbounded exponent range). The multiplication by a
225 power of 2 is exact, unless underflow/overflow occurs.
226 The tests on the exponent below avoid integer overflows
227 (ep[i] may take extreme values). */
228 mpfr_clear_flags ();
229 if (j == 0)
230 goto zero;
231 e = MPFR_GET_EXP (x1);
232 if (ep[i] < __gmpfr_emin - e) /* underflow */
233 {
234 mpfr_rnd_t r =
235 (rnd == MPFR_RNDN &&
236 (ep[i] < __gmpfr_emin - MPFR_GET_EXP (y) - 1 ||
237 IS_POW2 (sign * j))) ?
238 MPFR_RNDZ : (mpfr_rnd_t) rnd;
239 inex1 = mpfr_underflow (x1, r, sign);
240 flags1 = __gmpfr_flags;
241 }
242 else if (ep[i] > __gmpfr_emax - e) /* overflow */
243 {
244 inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
245 flags1 = __gmpfr_flags;
246 }
247 else
248 {
249 mpfr_set_exp (x1, ep[i] + e);
250 zero:
251 flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
252 }
253 }
254
255 /* Test mpfr_set_sj_2exp */
256 mpfr_clear_flags ();
257 inex2 = mpfr_set_sj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
258 flags2 = __gmpfr_flags;
259
260 if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
261 mpfr_equal_p (x1, x2)))
262 {
263 s = 's';
264 goto err_extreme;
265 }
266
267 if (j < 0)
268 continue;
269
270 /* Test mpfr_set_uj_2exp */
271 mpfr_clear_flags ();
272 inex2 = mpfr_set_uj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
273 flags2 = __gmpfr_flags;
274
275 if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
276 mpfr_equal_p (x1, x2)))
277 {
278 s = 'u';
279 err_extreme:
280 printf ("Error in extreme mpfr_set_%cj_2exp for i=%d j=%d %s\n",
281 s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
282 printf ("emin=%" MPFR_EXP_FSPEC "d "
283 "emax=%" MPFR_EXP_FSPEC "d\n",
284 (mpfr_eexp_t) __gmpfr_emin,
285 (mpfr_eexp_t) __gmpfr_emax);
286 #ifndef NPRINTF_J
287 printf ("e = %jd\n", em);
288 #endif
289 printf ("Expected ");
290 mpfr_dump (x1);
291 printf ("with inex = %d and flags =", inex1);
292 flags_out (flags1);
293 printf ("Got ");
294 mpfr_dump (x2);
295 printf ("with inex = %d and flags =", inex2);
296 flags_out (flags2);
297 exit (1);
298 }
299 }
300
301 mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
302 }
303
304 static void
test_2exp_extreme(void)305 test_2exp_extreme (void)
306 {
307 mpfr_exp_t emin, emax;
308
309 emin = mpfr_get_emin ();
310 emax = mpfr_get_emax ();
311
312 set_emin (MPFR_EMIN_MIN);
313 set_emax (MPFR_EMAX_MAX);
314 test_2exp_extreme_aux ();
315
316 set_emin (-REXP);
317 set_emax (REXP);
318 test_2exp_extreme_aux ();
319
320 set_emin (emin);
321 set_emax (emax);
322 }
323
324 int
main(int argc,char * argv[])325 main (int argc, char *argv[])
326 {
327 tests_start_mpfr ();
328
329 check_set_uj (2, 128, 50);
330 check_set_uj_2exp ();
331 check_set_sj ();
332 check_set_sj_2exp ();
333 test_2exp_extreme ();
334
335 tests_end_mpfr ();
336 return 0;
337 }
338
339 #endif
340