texceptions.c revision 1.1.1.5 1 /* Test file for features related to exceptions.
2
3 Copyright 2001-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 #include "mpfr-test.h"
24
25 #define PRINT_ERROR(s) do { printf ("%s\n", s); exit (1); } while (0)
26
27 /* Test powerof2 */
28 static void
29 check_powerof2 (void)
30 {
31 mpfr_t x;
32
33 mpfr_init (x);
34 mpfr_set_ui (x, 1, MPFR_RNDN);
35 MPFR_ASSERTN (mpfr_powerof2_raw (x));
36 mpfr_set_ui (x, 3, MPFR_RNDN);
37 MPFR_ASSERTN (!mpfr_powerof2_raw (x));
38 mpfr_clear (x);
39 }
40
41 /* Test default rounding mode */
42 static void
43 check_default_rnd (void)
44 {
45 int r;
46 mpfr_rnd_t t;
47 for(r = 0 ; r < MPFR_RND_MAX ; r++)
48 {
49 mpfr_set_default_rounding_mode ((mpfr_rnd_t) r);
50 t = (mpfr_get_default_rounding_mode) ();
51 if ((mpfr_rnd_t) r != t)
52 {
53 printf ("%s %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r),
54 mpfr_print_rnd_mode (t));
55 PRINT_ERROR ("ERROR in setting / getting default rounding mode (1)");
56 }
57 }
58 mpfr_set_default_rounding_mode ((mpfr_rnd_t) MPFR_RND_MAX);
59 if (mpfr_get_default_rounding_mode() != MPFR_RNDF)
60 PRINT_ERROR ("ERROR in setting / getting default rounding mode (2)");
61 mpfr_set_default_rounding_mode((mpfr_rnd_t) -1);
62 if (mpfr_get_default_rounding_mode() != MPFR_RNDF)
63 PRINT_ERROR ("ERROR in setting / getting default rounding mode (3)");
64 }
65
66 static void
67 check_emin_emax (void)
68 {
69 mpfr_exp_t old_emin, old_emax;
70
71 old_emin = mpfr_get_emin ();
72 old_emax = mpfr_get_emax ();
73
74 /* Check the functions not the macros ! */
75 if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0)
76 PRINT_ERROR ("set_emin failed!");
77 if ((mpfr_get_emin)() != MPFR_EMIN_MIN)
78 PRINT_ERROR ("get_emin FAILED!");
79 if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0)
80 PRINT_ERROR ("set_emin failed! (2)");
81
82 if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0)
83 PRINT_ERROR ("set_emax failed!");
84 if ((mpfr_get_emax)() != MPFR_EMAX_MAX)
85 PRINT_ERROR ("get_emax FAILED!");
86 if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0)
87 PRINT_ERROR ("set_emax failed! (2)");
88
89 if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN)
90 PRINT_ERROR ("get_emin_min");
91 if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX)
92 PRINT_ERROR ("get_emin_max");
93 if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN)
94 PRINT_ERROR ("get_emax_min");
95 if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX)
96 PRINT_ERROR ("get_emax_max");
97
98 set_emin (old_emin);
99 set_emax (old_emax);
100 }
101
102 static void
103 check_get_prec (void)
104 {
105 mpfr_t x;
106
107 mpfr_init2 (x, 17);
108 if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17)
109 PRINT_ERROR ("mpfr_get_prec");
110 mpfr_clear (x);
111 }
112
113 static void
114 mpfr_set_double_range (void)
115 {
116 mpfr_set_default_prec (54);
117 if (mpfr_get_default_prec () != 54)
118 PRINT_ERROR ("get_default_prec failed (1)");
119 mpfr_set_default_prec (53);
120 if ((mpfr_get_default_prec) () != 53)
121 PRINT_ERROR ("get_default_prec failed (2)");
122
123 /* in double precision format, the unbiased exponent is between 0 and
124 2047, where 0 is used for subnormal numbers, and 2047 for special
125 numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers
126 have an exponent between -1022 and 1023, corresponding to numbers
127 between 2^(-1022) and previous(2^(1024)).
128 (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).)
129
130 The smallest normal power of two is 1.0*2^(-1022).
131 The largest normal power of two is 2^1023.
132 (We have to add one for mpfr since mantissa are between 1/2 and 1.)
133 */
134
135 set_emin (-1021);
136 set_emax (1024);
137 }
138
139 static void
140 check_flags (void)
141 {
142 mpfr_t x;
143 mpfr_exp_t old_emin, old_emax;
144
145 old_emin = mpfr_get_emin ();
146 old_emax = mpfr_get_emax ();
147 mpfr_init (x);
148
149 /* Check the functions not the macros ! */
150 (mpfr_clear_flags)();
151 mpfr_set_double_range ();
152
153 mpfr_set_ui (x, 1, MPFR_RNDN);
154 (mpfr_clear_overflow)();
155 mpfr_mul_2ui (x, x, 1024, MPFR_RNDN);
156 if (!(mpfr_overflow_p)())
157 PRINT_ERROR ("ERROR: No overflow detected!\n");
158
159 (mpfr_clear_underflow)();
160 mpfr_set_ui (x, 1, MPFR_RNDN);
161 mpfr_div_2ui (x, x, 1025, MPFR_RNDN);
162 if (!(mpfr_underflow_p)())
163 PRINT_ERROR ("ERROR: No underflow detected!\n");
164
165 (mpfr_clear_nanflag)();
166 MPFR_SET_NAN(x);
167 mpfr_add (x, x, x, MPFR_RNDN);
168 if (!(mpfr_nanflag_p)())
169 PRINT_ERROR ("ERROR: No NaN flag!\n");
170
171 (mpfr_clear_inexflag)();
172 mpfr_set_ui(x, 2, MPFR_RNDN);
173 mpfr_cos(x, x, MPFR_RNDN);
174 if (!(mpfr_inexflag_p)())
175 PRINT_ERROR ("ERROR: No inexact flag!\n");
176
177 (mpfr_clear_erangeflag) ();
178 mpfr_set_ui (x, 1, MPFR_RNDN);
179 mpfr_mul_2ui (x, x, 1024, MPFR_RNDN);
180 mpfr_get_ui (x, MPFR_RNDN);
181 if (!(mpfr_erangeflag_p)())
182 PRINT_ERROR ("ERROR: No erange flag!\n");
183
184 mpfr_clear (x);
185 set_emin (old_emin);
186 set_emax (old_emax);
187 }
188
189 static void
190 test_set_underflow (void)
191 {
192 mpfr_t x, zero, min;
193 mpfr_ptr r[MPFR_RND_MAX];
194 int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */
195 int i;
196 int s;
197
198 mpfr_inits (x, zero, min, (mpfr_ptr) 0);
199 mpfr_set_ui (zero, 0, MPFR_RNDN);
200 mpfr_set_ui (min, 0, MPFR_RNDN);
201 mpfr_nextabove (min);
202 r[0] = r[2] = r[4] = min; /* RNDN, RNDU, RNDA */
203 r[1] = r[3] = zero; /* RNDZ, RNDD */
204 for (s = 1; s > 0; s = -1)
205 {
206 for (i = 0; i < MPFR_RND_MAX ; i++)
207 {
208 int j;
209 int inex;
210
211 j = s < 0 && i > 1 ? 5 - i : i;
212 inex = mpfr_underflow (x, (mpfr_rnd_t) i, s);
213 /* for RNDF, inex has no meaning, just check that x is either
214 min or zero */
215 if (i == MPFR_RNDF)
216 {
217 if (mpfr_cmp (x, min) && mpfr_cmp (x, zero))
218 {
219 printf ("Error in test_set_underflow, sign = %d,"
220 " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
221 printf ("Got\n");
222 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
223 printf ("\ninstead of\n");
224 mpfr_out_str (stdout, 2, 0, zero, MPFR_RNDN);
225 printf ("\nor\n");
226 mpfr_out_str (stdout, 2, 0, min, MPFR_RNDN);
227 printf ("\n");
228 exit (1);
229 }
230 }
231 else if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0)
232 {
233 printf ("Error in test_set_underflow, sign = %d,"
234 " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
235 printf ("Got\n");
236 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
237 printf (", inex = %d\ninstead of\n", inex);
238 mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN);
239 printf (", inex = %d\n", t[j]);
240 exit (1);
241 }
242 }
243 mpfr_neg (zero, zero, MPFR_RNDN);
244 mpfr_neg (min, min, MPFR_RNDN);
245 }
246 mpfr_clears (x, zero, min, (mpfr_ptr) 0);
247 }
248
249 static void
250 test_set_overflow (void)
251 {
252 mpfr_t x, inf, max;
253 mpfr_ptr r[MPFR_RND_MAX];
254 int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */
255 int i;
256 int s;
257
258 mpfr_inits2 (32, x, inf, max, (mpfr_ptr) 0);
259 mpfr_set_inf (inf, 1);
260 mpfr_set_inf (max, 1);
261 mpfr_nextbelow (max);
262 r[0] = r[2] = r[4] = inf; /* RNDN, RNDU, RNDA */
263 r[1] = r[3] = max; /* RNDZ, RNDD */
264 for (s = 1; s > 0; s = -1)
265 {
266 for (i = 0; i < MPFR_RND_MAX ; i++)
267 {
268 int j;
269 int inex;
270
271 j = s < 0 && i > 1 ? 5 - i : i;
272 inex = mpfr_overflow (x, (mpfr_rnd_t) i, s);
273 /* for RNDF, inex has no meaning, just check that x is either
274 max or inf */
275 if (i == MPFR_RNDF)
276 {
277 if (mpfr_cmp (x, max) && mpfr_cmp (x, inf))
278 {
279 printf ("Error in test_set_overflow, sign = %d,"
280 " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
281 printf ("Got\n");
282 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
283 printf ("\ninstead of\n");
284 mpfr_out_str (stdout, 2, 0, max, MPFR_RNDN);
285 printf ("\nor\n");
286 mpfr_out_str (stdout, 2, 0, inf, MPFR_RNDN);
287 printf ("\n");
288 exit (1);
289 }
290 }
291 else if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0)
292 {
293 printf ("Error in test_set_overflow, sign = %d,"
294 " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
295 printf ("Got\n");
296 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
297 printf (", inex = %d\ninstead of\n", inex);
298 mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN);
299 printf (", inex = %d\n", t[j]);
300 exit (1);
301 }
302 }
303 mpfr_neg (inf, inf, MPFR_RNDN);
304 mpfr_neg (max, max, MPFR_RNDN);
305 }
306 mpfr_clears (x, inf, max, (mpfr_ptr) 0);
307 }
308
309 static void
310 check_set (void)
311 {
312 mpfr_clear_flags ();
313
314 mpfr_set_overflow ();
315 MPFR_ASSERTN ((mpfr_overflow_p) ());
316 mpfr_set_underflow ();
317 MPFR_ASSERTN ((mpfr_underflow_p) ());
318 mpfr_set_divby0 ();
319 MPFR_ASSERTN ((mpfr_divby0_p) ());
320 mpfr_set_nanflag ();
321 MPFR_ASSERTN ((mpfr_nanflag_p) ());
322 mpfr_set_inexflag ();
323 MPFR_ASSERTN ((mpfr_inexflag_p) ());
324 mpfr_set_erangeflag ();
325 MPFR_ASSERTN ((mpfr_erangeflag_p) ());
326
327 MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL);
328
329 mpfr_clear_overflow ();
330 MPFR_ASSERTN (! (mpfr_overflow_p) ());
331 mpfr_clear_underflow ();
332 MPFR_ASSERTN (! (mpfr_underflow_p) ());
333 mpfr_clear_divby0 ();
334 MPFR_ASSERTN (! (mpfr_divby0_p) ());
335 mpfr_clear_nanflag ();
336 MPFR_ASSERTN (! (mpfr_nanflag_p) ());
337 mpfr_clear_inexflag ();
338 MPFR_ASSERTN (! (mpfr_inexflag_p) ());
339 mpfr_clear_erangeflag ();
340 MPFR_ASSERTN (! (mpfr_erangeflag_p) ());
341
342 MPFR_ASSERTN (__gmpfr_flags == 0);
343
344 (mpfr_set_overflow) ();
345 MPFR_ASSERTN (mpfr_overflow_p ());
346 (mpfr_set_underflow) ();
347 MPFR_ASSERTN (mpfr_underflow_p ());
348 (mpfr_set_divby0) ();
349 MPFR_ASSERTN (mpfr_divby0_p ());
350 (mpfr_set_nanflag) ();
351 MPFR_ASSERTN (mpfr_nanflag_p ());
352 (mpfr_set_inexflag) ();
353 MPFR_ASSERTN (mpfr_inexflag_p ());
354 (mpfr_set_erangeflag) ();
355 MPFR_ASSERTN (mpfr_erangeflag_p ());
356
357 MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL);
358
359 (mpfr_clear_overflow) ();
360 MPFR_ASSERTN (! mpfr_overflow_p ());
361 (mpfr_clear_underflow) ();
362 MPFR_ASSERTN (! mpfr_underflow_p ());
363 (mpfr_clear_divby0) ();
364 MPFR_ASSERTN (! mpfr_divby0_p ());
365 (mpfr_clear_nanflag) ();
366 MPFR_ASSERTN (! mpfr_nanflag_p ());
367 (mpfr_clear_inexflag) ();
368 MPFR_ASSERTN (! mpfr_inexflag_p ());
369 (mpfr_clear_erangeflag) ();
370 MPFR_ASSERTN (! mpfr_erangeflag_p ());
371
372 MPFR_ASSERTN (__gmpfr_flags == 0);
373 }
374
375 /* Note: this test assumes that mpfr_flags_* can be implemented as both
376 a function and a macro. Thus in such a case, both implementations are
377 tested. */
378 static void
379 check_groups (void)
380 {
381 int i, j;
382 for (i = 0; i < 200; i++)
383 {
384 mpfr_flags_t f1, f2, mask;
385
386 f1 = __gmpfr_flags;
387 MPFR_ASSERTN (mpfr_flags_save () == f1);
388 MPFR_ASSERTN ((mpfr_flags_save) () == f1);
389 MPFR_ASSERTN (__gmpfr_flags == f1);
390 mask = randlimb () & MPFR_FLAGS_ALL;
391 if (randlimb () & 1)
392 mpfr_flags_set (mask);
393 else
394 (mpfr_flags_set) (mask);
395 for (j = 1; j <= MPFR_FLAGS_ALL; j <<= 1)
396 if ((__gmpfr_flags & j) != ((mask & j) != 0 ? j : (f1 & j)))
397 {
398 printf ("mpfr_flags_set error: old = 0x%lx, group = 0x%lx, "
399 "new = 0x%lx, j = 0x%lx\n",
400 (unsigned long) f1, (unsigned long) mask,
401 (unsigned long) __gmpfr_flags, (unsigned long) j);
402 exit (1);
403 }
404
405 f2 = __gmpfr_flags;
406 mask = randlimb () & MPFR_FLAGS_ALL;
407 if (randlimb () & 1)
408 mpfr_flags_clear (mask);
409 else
410 (mpfr_flags_clear) (mask);
411 for (j = 1; j <= MPFR_FLAGS_ALL; j <<= 1)
412 if ((__gmpfr_flags & j) != ((mask & j) != 0 ? 0 : (f2 & j)))
413 {
414 printf ("mpfr_flags_clear error: old = 0x%lx, group = 0x%lx, "
415 "new = 0x%lx, j = 0x%lx\n",
416 (unsigned long) f2, (unsigned long) mask,
417 (unsigned long) __gmpfr_flags, (unsigned long) j);
418 exit (1);
419 }
420
421 mask = randlimb () & MPFR_FLAGS_ALL;
422 f2 = (randlimb () & 1) ?
423 mpfr_flags_test (mask) : (mpfr_flags_test) (mask);
424 for (j = 1; j <= MPFR_FLAGS_ALL; j <<= 1)
425 if ((f2 & j) != ((mask & j) != 0 ? (__gmpfr_flags & j) : 0))
426 {
427 printf ("mpfr_flags_test error: current = 0x%lx, mask = 0x%lx, "
428 "res = 0x%lx, j = 0x%lx\n",
429 (unsigned long) __gmpfr_flags, (unsigned long) mask,
430 (unsigned long) f2, (unsigned long) j);
431 exit (1);
432 }
433
434 f2 = __gmpfr_flags;
435 if (randlimb () & 1)
436 mpfr_flags_restore (f1, mask);
437 else
438 (mpfr_flags_restore) (f1, mask);
439 for (j = 1; j <= MPFR_FLAGS_ALL; j <<= 1)
440 if ((__gmpfr_flags & j) != (((mask & j) != 0 ? f1 : f2) & j))
441 {
442 printf ("mpfr_flags_restore error: old = 0x%lx, flags = 0x%lx, "
443 "mask = 0x%lx, new = 0x%lx, j = 0x%lx\n",
444 (unsigned long) f2, (unsigned long) f1,
445 (unsigned long) mask, (unsigned long) __gmpfr_flags,
446 (unsigned long) j);
447 exit (1);
448 }
449 }
450 }
451
452 int
453 main (int argc, char *argv[])
454 {
455 mpfr_t x, y;
456 mpfr_exp_t emin, emax;
457
458 tests_start_mpfr ();
459
460 test_set_underflow ();
461 test_set_overflow ();
462 check_default_rnd();
463
464 mpfr_init (x);
465 mpfr_init (y);
466
467 emin = mpfr_get_emin ();
468 emax = mpfr_get_emax ();
469 if (emin >= emax)
470 {
471 printf ("Error: emin >= emax\n");
472 exit (1);
473 }
474
475 mpfr_set_ui (x, 1, MPFR_RNDN);
476 mpfr_mul_2ui (x, x, 1024, MPFR_RNDN);
477 mpfr_set_double_range ();
478 mpfr_check_range (x, 0, MPFR_RNDN);
479 if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
480 {
481 printf ("Error: 2^1024 rounded to nearest should give +Inf\n");
482 exit (1);
483 }
484
485 set_emax (1025);
486 mpfr_set_ui (x, 1, MPFR_RNDN);
487 mpfr_mul_2ui (x, x, 1024, MPFR_RNDN);
488 mpfr_set_double_range ();
489 mpfr_check_range (x, 0, MPFR_RNDD);
490 if (!mpfr_number_p (x))
491 {
492 printf ("Error: 2^1024 rounded down should give a normal number\n");
493 exit (1);
494 }
495
496 mpfr_set_ui (x, 1, MPFR_RNDN);
497 mpfr_mul_2ui (x, x, 1023, MPFR_RNDN);
498 mpfr_add (x, x, x, MPFR_RNDN);
499 if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
500 {
501 printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n");
502 printf ("emax = %ld\n", (long) mpfr_get_emax ());
503 printf ("got "); mpfr_dump (x);
504 exit (1);
505 }
506
507 mpfr_set_ui (x, 1, MPFR_RNDN);
508 mpfr_mul_2ui (x, x, 1023, MPFR_RNDN);
509 mpfr_add (x, x, x, MPFR_RNDD);
510 if (!mpfr_number_p (x))
511 {
512 printf ("Error: x+x rounded down for x=2^1023 should give"
513 " a normal number\n");
514 exit (1);
515 }
516
517 mpfr_set_ui (x, 1, MPFR_RNDN);
518 mpfr_div_2ui (x, x, 1022, MPFR_RNDN);
519 mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */
520 mpfr_sub (y, y, x, MPFR_RNDZ);
521 if (mpfr_cmp_ui (y, 0))
522 {
523 printf ("Error: y-x rounded to zero should give 0"
524 " for y=3/2*2^(-1022), x=2^(-1022)\n");
525 printf ("Got "); mpfr_dump (y);
526 exit (1);
527 }
528
529 set_emin (-1026);
530 mpfr_set_ui (x, 1, MPFR_RNDN);
531 mpfr_div_2ui (x, x, 1025, MPFR_RNDN);
532 mpfr_set_double_range ();
533 mpfr_check_range (x, 0, MPFR_RNDN);
534 if (!MPFR_IS_ZERO (x) )
535 {
536 printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n");
537 printf ("emin = %ld\n", (long) mpfr_get_emin ());
538 printf ("got "); mpfr_dump (x);
539 exit (1);
540 }
541
542 mpfr_clear (x);
543 mpfr_clear (y);
544
545 set_emin (emin);
546 set_emax (emax);
547
548 check_emin_emax();
549 check_flags();
550 check_get_prec ();
551 check_powerof2 ();
552 check_set ();
553 check_groups ();
554
555 tests_end_mpfr ();
556 return 0;
557 }
558