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