1 /* Generic test file for functions with one or two arguments (the second being 2 either mpfr_t or double or unsigned long). 3 4 Copyright 2001-2018 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 http://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 TWO_ARGS for two-argument functions like mpfr_pow. 25 Define DOUBLE_ARG1 or DOUBLE_ARG2 for function with a double operand in 26 first or second place like sub_d or d_sub. 27 Define ULONG_ARG1 or ULONG_ARG2 for function with an unsigned long 28 operand in first or second place like sub_ui or ui_sub. */ 29 30 /* TODO: Add support for type long and extreme integer values, as done 31 in tgeneric_ui.c; then tgeneric_ui.c could probably disappear. */ 32 33 #ifndef ONE_ARG 34 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) || \ 35 defined(ULONG_ARG1) || defined(ULONG_ARG2) 36 #define TWO_ARGS_ALL 37 #endif 38 #endif 39 40 #if defined(TWO_ARGS_ALL) || defined(ULONG_ARG1) || defined(ULONG_ARG2) 41 #define NEED_U 42 #endif 43 44 #ifndef TEST_RANDOM_POS 45 /* For the random function: one number on two is negative. */ 46 #define TEST_RANDOM_POS 256 47 #endif 48 49 #ifndef TEST_RANDOM_POS2 50 /* For the random function: one number on two is negative. */ 51 #define TEST_RANDOM_POS2 256 52 #endif 53 54 #ifndef TEST_RANDOM_EMIN 55 #define TEST_RANDOM_EMIN -256 56 #endif 57 58 #ifndef TEST_RANDOM_EMAX 59 #define TEST_RANDOM_EMAX 255 60 #endif 61 62 #ifndef TEST_RANDOM_ALWAYS_SCALE 63 #define TEST_RANDOM_ALWAYS_SCALE 0 64 #endif 65 66 /* If the MPFR_SUSPICIOUS_OVERFLOW test fails but this is not a bug, 67 then define TGENERIC_SO_TEST with an adequate test (possibly 0) to 68 omit this particular case. */ 69 #ifndef TGENERIC_SO_TEST 70 #define TGENERIC_SO_TEST 1 71 #endif 72 73 /* The (void *) below is needed to avoid a warning with gcc 4.2+ and functions 74 * with 2 arguments. See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36299>. 75 */ 76 #define TGENERIC_FAIL(S, X, U) \ 77 do \ 78 { \ 79 printf ("tgeneric: %s\nx = ", (S)); \ 80 mpfr_dump (X);; \ 81 if ((void *) (U) != 0) \ 82 { \ 83 printf ("u = "); \ 84 mpfr_dump (U); \ 85 } \ 86 printf ("yprec = %u, rnd_mode = %s, inexact = %d\nflags =", \ 87 (unsigned int) yprec, mpfr_print_rnd_mode (rnd), \ 88 compare); \ 89 flags_out (flags); \ 90 exit (1); \ 91 } \ 92 while (0) 93 94 #define TGENERIC_CHECK_AUX(S, EXPR, U) \ 95 do \ 96 if (!(EXPR)) \ 97 TGENERIC_FAIL (S " for " MAKE_STR(TEST_FUNCTION), x, U); \ 98 while (0) 99 100 #undef TGENERIC_CHECK 101 #if defined(TWO_ARGS_ALL) 102 #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, u) 103 #else 104 #define TGENERIC_CHECK(S, EXPR) TGENERIC_CHECK_AUX(S, EXPR, 0) 105 #endif 106 107 #ifdef MPFR_DEBUG_TGENERIC 108 #define TGENERIC_IAUX(F,P,X,U) \ 109 do \ 110 { \ 111 printf ("tgeneric: testing function " STR(F) \ 112 ", %s, target prec = %lu\nx = ", \ 113 mpfr_print_rnd_mode (rnd), (unsigned long) (P)); \ 114 mpfr_dump (X); \ 115 if ((void *) (U) != 0) \ 116 { \ 117 printf ("u = "); \ 118 mpfr_dump (U); \ 119 } \ 120 } \ 121 while (0) 122 #undef TGENERIC_INFO 123 #if defined(TWO_ARGS_ALL) 124 #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,u) 125 #else 126 #define TGENERIC_INFO(F,P) TGENERIC_IAUX(F,P,x,0) 127 #endif 128 #endif /* MPFR_DEBUG_TGENERIC */ 129 130 /* For some functions (for example cos), the argument reduction is too 131 expensive when using mpfr_get_emax(). Then simply define REDUCE_EMAX 132 to some reasonable value before including tgeneric.c. */ 133 #ifndef REDUCE_EMAX 134 #define REDUCE_EMAX mpfr_get_emax () 135 #endif 136 137 /* same for mpfr_get_emin() */ 138 #ifndef REDUCE_EMIN 139 #define REDUCE_EMIN mpfr_get_emin () 140 #endif 141 142 static void 143 test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax) 144 { 145 mpfr_prec_t prec, xprec, yprec; 146 mpfr_t x, y, z, t, w, yd, yu; 147 #ifdef NEED_U 148 mpfr_t u; 149 #endif 150 #if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 151 double d; 152 #endif 153 #if defined(ULONG_ARG1) || defined(ULONG_ARG2) 154 unsigned long i; 155 #endif 156 mpfr_rnd_t rnd; 157 int inexact, compare, compare2; 158 unsigned int n; 159 unsigned long ctrt = 0, ctrn = 0; 160 mpfr_exp_t old_emin, old_emax; 161 162 old_emin = mpfr_get_emin (); 163 old_emax = mpfr_get_emax (); 164 165 mpfr_inits2 (MPFR_PREC_MIN, x, y, yd, yu, z, t, w, (mpfr_ptr) 0); 166 #ifdef NEED_U 167 mpfr_init2 (u, MPFR_PREC_MIN); 168 #endif 169 170 /* generic test */ 171 for (prec = p0; prec <= p1; prec++) 172 { 173 /* Number of overflow/underflow tests for each precision. 174 Since MPFR uses several algorithms and there may also be 175 early overflow/underflow detection, several tests may be 176 needed to detect a bug. */ 177 int test_of = 3, test_uf = 3; 178 179 mpfr_set_prec (z, prec); 180 mpfr_set_prec (t, prec); 181 yprec = prec + 10; 182 mpfr_set_prec (y, yprec); 183 mpfr_set_prec (yd, yprec); 184 mpfr_set_prec (yu, yprec); 185 mpfr_set_prec (w, yprec); 186 187 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 188 #define NSPEC 9 189 #else 190 #define NSPEC 5 191 #endif 192 193 /* Note: in precision p1, we test NSPEC special cases. */ 194 for (n = 0; n < (prec == p1 ? nmax + NSPEC : nmax); n++) 195 { 196 int infinite_input = 0; 197 mpfr_flags_t flags; 198 mpfr_exp_t oemin, oemax; 199 200 xprec = prec; 201 if (randlimb () & 1) 202 { 203 /* In half cases, modify the precision of the inputs: 204 If the base precision (for the result) is small, 205 take a larger input precision in general, else 206 take a smaller precision. */ 207 xprec *= (prec < 16 ? 256.0 : 1.0) * 208 (double) randlimb () / MPFR_LIMB_MAX; 209 if (xprec < MPFR_PREC_MIN) 210 xprec = MPFR_PREC_MIN; 211 } 212 mpfr_set_prec (x, xprec); 213 #if defined(TWO_ARGS) 214 mpfr_set_prec (u, xprec); 215 #elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 216 mpfr_set_prec (u, IEEE_DBL_MANT_DIG); 217 #elif defined(ULONG_ARG1) || defined(ULONG_ARG2) 218 mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT); 219 #endif 220 221 if (n >= NSPEC || prec < p1) 222 { 223 #if defined(RAND_FUNCTION) 224 RAND_FUNCTION (x); 225 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 226 RAND_FUNCTION (u); 227 #endif 228 #else /* ! defined(RAND_FUNCTION) */ 229 tests_default_random (x, TEST_RANDOM_POS, 230 TEST_RANDOM_EMIN, TEST_RANDOM_EMAX, 231 TEST_RANDOM_ALWAYS_SCALE); 232 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 233 tests_default_random (u, TEST_RANDOM_POS2, 234 TEST_RANDOM_EMIN, TEST_RANDOM_EMAX, 235 TEST_RANDOM_ALWAYS_SCALE); 236 #endif 237 #endif /* ! defined(RAND_FUNCTION) */ 238 } 239 else 240 { 241 /* Special cases tested in precision p1 if n < NSPEC. They are 242 useful really in the extended exponent range. */ 243 #if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO) 244 goto next_n; 245 #endif 246 set_emin (MPFR_EMIN_MIN); 247 set_emax (MPFR_EMAX_MAX); 248 if (n == 0) 249 { 250 mpfr_set_nan (x); 251 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 252 #if defined(RAND_FUNCTION) 253 RAND_FUNCTION (u); 254 #else 255 tests_default_random (u, TEST_RANDOM_POS2, 256 TEST_RANDOM_EMIN, TEST_RANDOM_EMAX, 257 TEST_RANDOM_ALWAYS_SCALE); 258 #endif 259 #endif 260 } 261 else if (n <= 2) 262 { 263 MPFR_ASSERTN (n == 1 || n == 2); 264 mpfr_set_si (x, n == 1 ? 1 : -1, MPFR_RNDN); 265 mpfr_set_exp (x, REDUCE_EMIN); 266 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 267 mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN); 268 mpfr_set_exp (u, REDUCE_EMIN); 269 #endif 270 } 271 else if (n <= 4) 272 { 273 MPFR_ASSERTN (n == 3 || n == 4); 274 mpfr_set_si (x, n == 3 ? 1 : -1, MPFR_RNDN); 275 mpfr_setmax (x, REDUCE_EMAX); 276 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 277 mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN); 278 mpfr_setmax (u, REDUCE_EMAX); 279 #endif 280 } 281 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 282 else if (n <= 6) 283 { 284 MPFR_ASSERTN (n == 5 || n == 6); 285 mpfr_set_si (x, n == 5 ? 1 : -1, MPFR_RNDN); 286 mpfr_set_exp (x, REDUCE_EMIN); 287 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 288 mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN); 289 mpfr_setmax (u, REDUCE_EMAX); 290 #endif 291 } 292 else 293 { 294 MPFR_ASSERTN (n == 7 || n == 8); 295 mpfr_set_si (x, n == 7 ? 1 : -1, MPFR_RNDN); 296 mpfr_setmax (x, REDUCE_EMAX); 297 #if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2) 298 mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN); 299 mpfr_set_exp (u, REDUCE_EMIN); 300 #endif 301 } 302 #endif /* two arguments */ 303 } 304 305 #if defined(ULONG_ARG1) || defined(ULONG_ARG2) 306 i = randlimb (); 307 inexact = mpfr_set_ui (u, i, MPFR_RNDN); 308 MPFR_ASSERTN (inexact == 0); 309 #endif 310 311 /* Exponent range for the test. */ 312 oemin = mpfr_get_emin (); 313 oemax = mpfr_get_emax (); 314 315 rnd = RND_RAND (); 316 mpfr_clear_flags (); 317 #ifdef MPFR_DEBUG_TGENERIC 318 TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y)); 319 #endif 320 #if defined(TWO_ARGS) 321 compare = TEST_FUNCTION (y, x, u, rnd); 322 #elif defined(DOUBLE_ARG1) 323 d = mpfr_get_d (u, rnd); 324 compare = TEST_FUNCTION (y, d, x, rnd); 325 /* d can be infinite due to overflow in mpfr_get_d */ 326 infinite_input |= DOUBLE_ISINF (d); 327 #elif defined(DOUBLE_ARG2) 328 d = mpfr_get_d (u, rnd); 329 compare = TEST_FUNCTION (y, x, d, rnd); 330 /* d can be infinite due to overflow in mpfr_get_d */ 331 infinite_input |= DOUBLE_ISINF (d); 332 #elif defined(ULONG_ARG1) && defined(ONE_ARG) 333 compare = TEST_FUNCTION (y, i, rnd); 334 #elif defined(ULONG_ARG1) 335 compare = TEST_FUNCTION (y, i, x, rnd); 336 #elif defined(ULONG_ARG2) 337 compare = TEST_FUNCTION (y, x, i, rnd); 338 #else 339 compare = TEST_FUNCTION (y, x, rnd); 340 #endif 341 flags = __gmpfr_flags; 342 if (mpfr_get_emin () != oemin || 343 mpfr_get_emax () != oemax) 344 { 345 printf ("tgeneric: the exponent range has been modified" 346 " by the tested function!\n"); 347 exit (1); 348 } 349 if (rnd != MPFR_RNDF) 350 TGENERIC_CHECK ("bad inexact flag", 351 (compare != 0) ^ (mpfr_inexflag_p () == 0)); 352 ctrt++; 353 354 /* If rnd = RNDF, check that we obtain the same result as 355 RNDD or RNDU. */ 356 if (rnd == MPFR_RNDF) 357 { 358 #if defined(TWO_ARGS) 359 TEST_FUNCTION (yd, x, u, MPFR_RNDD); 360 TEST_FUNCTION (yu, x, u, MPFR_RNDU); 361 #elif defined(DOUBLE_ARG1) 362 d = mpfr_get_d (u, MPFR_RNDD); 363 TEST_FUNCTION (yd, d, x, MPFR_RNDD); 364 d = mpfr_get_d (u, MPFR_RNDU); 365 TEST_FUNCTION (yu, d, x, MPFR_RNDU); 366 #elif defined(DOUBLE_ARG2) 367 d = mpfr_get_d (u, MPFR_RNDD); 368 TEST_FUNCTION (yd, x, d, MPFR_RNDD); 369 d = mpfr_get_d (u, MPFR_RNDU); 370 TEST_FUNCTION (yu, x, d, MPFR_RNDU); 371 #elif defined(ULONG_ARG1) && defined(ONE_ARG) 372 TEST_FUNCTION (yd, i, MPFR_RNDD); 373 TEST_FUNCTION (yu, i, MPFR_RNDU); 374 #elif defined(ULONG_ARG1) 375 TEST_FUNCTION (yd, i, x, MPFR_RNDD); 376 TEST_FUNCTION (yu, i, x, MPFR_RNDU); 377 #elif defined(ULONG_ARG2) 378 TEST_FUNCTION (yd, x, i, MPFR_RNDD); 379 TEST_FUNCTION (yu, x, i, MPFR_RNDU); 380 #else 381 TEST_FUNCTION (yd, x, MPFR_RNDD); 382 TEST_FUNCTION (yu, x, MPFR_RNDU); 383 #endif 384 if (! (SAME_VAL (y, yd) || SAME_VAL (y, yu))) 385 { 386 printf ("For RNDF, result does not match RNDD nor RNDU\n"); 387 printf ("x = "); mpfr_dump (x); 388 #ifdef NEED_U 389 printf ("u = "); mpfr_dump (u); 390 #endif 391 #if defined(ULONG_ARG1) || defined(ULONG_ARG2) 392 printf ("i = %lu\n", i); 393 #endif 394 printf ("yd (RNDD) = "); mpfr_dump (yd); 395 printf ("yu (RNDU) = "); mpfr_dump (yu); 396 printf ("y (RNDF) = "); mpfr_dump (y); 397 exit (1); 398 } 399 } 400 401 /* Tests in a reduced exponent range. */ 402 { 403 mpfr_flags_t oldflags = flags; 404 mpfr_exp_t e, emin, emax; 405 406 /* Determine the smallest exponent range containing the 407 exponents of the mpfr_t inputs (x, and u if TWO_ARGS) 408 and output (y). */ 409 emin = MPFR_EMAX_MAX; 410 emax = MPFR_EMIN_MIN; 411 if (MPFR_IS_PURE_FP (x)) 412 { 413 e = MPFR_GET_EXP (x); 414 if (e < emin) 415 emin = e; 416 if (e > emax) 417 emax = e; 418 } 419 #if defined(TWO_ARGS) 420 if (MPFR_IS_PURE_FP (u)) 421 { 422 e = MPFR_GET_EXP (u); 423 if (e < emin) 424 emin = e; 425 if (e > emax) 426 emax = e; 427 } 428 #endif 429 if (MPFR_IS_PURE_FP (y)) 430 { 431 e = MPFR_GET_EXP (y); /* exponent of the result */ 432 433 if (test_of > 0 && e - 1 >= emax) /* overflow test */ 434 { 435 mpfr_flags_t ex_flags; 436 437 /* Exponent e of the result > exponents of the inputs; 438 let's set emax to e - 1, so that one should get an 439 overflow. */ 440 mpfr_set_emax (e - 1); 441 #ifdef MPFR_DEBUG_TGENERIC 442 printf ("tgeneric: overflow test (emax = %" 443 MPFR_EXP_FSPEC "d)\n", 444 (mpfr_eexp_t) __gmpfr_emax); 445 #endif 446 mpfr_clear_flags (); 447 #if defined(TWO_ARGS) 448 inexact = TEST_FUNCTION (w, x, u, rnd); 449 #elif defined(DOUBLE_ARG1) 450 inexact = TEST_FUNCTION (w, d, x, rnd); 451 #elif defined(DOUBLE_ARG2) 452 inexact = TEST_FUNCTION (w, x, d, rnd); 453 #elif defined(ULONG_ARG1) && defined(ONE_ARG) 454 inexact = TEST_FUNCTION (w, i, rnd); 455 #elif defined(ULONG_ARG1) 456 inexact = TEST_FUNCTION (w, i, x, rnd); 457 #elif defined(ULONG_ARG2) 458 inexact = TEST_FUNCTION (w, x, i, rnd); 459 #else 460 inexact = TEST_FUNCTION (w, x, rnd); 461 #endif 462 flags = __gmpfr_flags; 463 mpfr_set_emax (oemax); 464 ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT; 465 /* For RNDF, this test makes no sense, since RNDF 466 might return either the maximal floating-point 467 value or infinity, and the flags might differ in 468 those two cases. */ 469 if (flags != ex_flags && rnd != MPFR_RNDF) 470 { 471 printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION) 472 ", reduced exponent range [%" 473 MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC 474 "d] (overflow test) on:\n", 475 (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1); 476 printf ("x = "); 477 mpfr_dump (x); 478 #ifdef NEED_U 479 printf ("u = "); 480 mpfr_dump (u); 481 #endif 482 printf ("yprec = %u, rnd_mode = %s\n", 483 (unsigned int) yprec, 484 mpfr_print_rnd_mode (rnd)); 485 printf ("Expected flags ="); 486 flags_out (ex_flags); 487 printf (" got flags ="); 488 flags_out (flags); 489 printf ("inex = %d, w = ", inexact); 490 mpfr_dump (w); 491 exit (1); 492 } 493 test_of--; 494 } 495 496 if (test_uf > 0 && e + 1 <= emin) /* underflow test */ 497 { 498 mpfr_flags_t ex_flags; 499 500 /* Exponent e of the result < exponents of the inputs; 501 let's set emin to e + 1, so that one should get an 502 underflow. */ 503 mpfr_set_emin (e + 1); 504 #ifdef MPFR_DEBUG_TGENERIC 505 printf ("tgeneric: underflow test (emin = %" 506 MPFR_EXP_FSPEC "d)\n", 507 (mpfr_eexp_t) __gmpfr_emin); 508 #endif 509 mpfr_clear_flags (); 510 #if defined(TWO_ARGS) 511 inexact = TEST_FUNCTION (w, x, u, rnd); 512 #elif defined(DOUBLE_ARG1) 513 inexact = TEST_FUNCTION (w, d, x, rnd); 514 #elif defined(DOUBLE_ARG2) 515 inexact = TEST_FUNCTION (w, x, d, rnd); 516 #elif defined(ULONG_ARG1) && defined(ONE_ARG) 517 inexact = TEST_FUNCTION (w, i, rnd); 518 #elif defined(ULONG_ARG1) 519 inexact = TEST_FUNCTION (w, i, x, rnd); 520 #elif defined(ULONG_ARG2) 521 inexact = TEST_FUNCTION (w, x, i, rnd); 522 #else 523 inexact = TEST_FUNCTION (w, x, rnd); 524 #endif 525 flags = __gmpfr_flags; 526 mpfr_set_emin (oemin); 527 ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT; 528 /* For RNDF, this test makes no sense, since RNDF 529 might return either the maximal floating-point 530 value or infinity, and the flags might differ in 531 those two cases. */ 532 if (flags != ex_flags && rnd != MPFR_RNDF) 533 { 534 printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION) 535 ", reduced exponent range [%" 536 MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC 537 "d] (underflow test) on:\n", 538 (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax); 539 printf ("x = "); 540 mpfr_dump (x); 541 #ifdef NEED_U 542 printf ("u = "); 543 mpfr_dump (u); 544 #endif 545 printf ("yprec = %u, rnd_mode = %s\n", 546 (unsigned int) yprec, 547 mpfr_print_rnd_mode (rnd)); 548 printf ("Expected flags ="); 549 flags_out (ex_flags); 550 printf (" got flags ="); 551 flags_out (flags); 552 printf ("inex = %d, w = ", inexact); 553 mpfr_dump (w); 554 exit (1); 555 } 556 test_uf--; 557 } 558 559 if (e < emin) 560 emin = e; 561 if (e > emax) 562 emax = e; 563 } /* MPFR_IS_PURE_FP (y) */ 564 565 if (emin > emax) 566 emin = emax; /* case where all values are singular */ 567 568 /* Consistency test in a reduced exponent range. Doing it 569 for the first 10 samples and for prec == p1 (which has 570 some special cases) should be sufficient. */ 571 if (ctrt <= 10 || prec == p1) 572 { 573 mpfr_set_emin (emin); 574 mpfr_set_emax (emax); 575 #ifdef MPFR_DEBUG_TGENERIC 576 /* Useful information in case of assertion failure. */ 577 printf ("tgeneric: reduced exponent range [%" 578 MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n", 579 (mpfr_eexp_t) emin, (mpfr_eexp_t) emax); 580 #endif 581 mpfr_clear_flags (); 582 #if defined(TWO_ARGS) 583 inexact = TEST_FUNCTION (w, x, u, rnd); 584 #elif defined(DOUBLE_ARG1) 585 inexact = TEST_FUNCTION (w, d, x, rnd); 586 #elif defined(DOUBLE_ARG2) 587 inexact = TEST_FUNCTION (w, x, d, rnd); 588 #elif defined(ULONG_ARG1) && defined(ONE_ARG) 589 inexact = TEST_FUNCTION (w, i, rnd); 590 #elif defined(ULONG_ARG1) 591 inexact = TEST_FUNCTION (w, i, x, rnd); 592 #elif defined(ULONG_ARG2) 593 inexact = TEST_FUNCTION (w, x, i, rnd); 594 #else 595 inexact = TEST_FUNCTION (w, x, rnd); 596 #endif 597 flags = __gmpfr_flags; 598 mpfr_set_emin (oemin); 599 mpfr_set_emax (oemax); 600 /* That test makes no sense for RNDF. */ 601 if (rnd != MPFR_RNDF && ! (SAME_VAL (w, y) && 602 SAME_SIGN (inexact, compare) && 603 flags == oldflags)) 604 { 605 printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION) 606 ", reduced exponent range [%" 607 MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n", 608 (mpfr_eexp_t) emin, (mpfr_eexp_t) emax); 609 printf ("x = "); 610 mpfr_dump (x); 611 #ifdef NEED_U 612 printf ("u = "); 613 mpfr_dump (u); 614 #endif 615 printf ("yprec = %u, rnd_mode = %s\n", 616 (unsigned int) yprec, mpfr_print_rnd_mode (rnd)); 617 printf ("Expected:\n y = "); 618 mpfr_dump (y); 619 printf (" inex = %d, flags =", compare); 620 flags_out (oldflags); 621 printf ("Got:\n w = "); 622 mpfr_dump (w); 623 printf (" inex = %d, flags =", inexact); 624 flags_out (flags); 625 exit (1); 626 } 627 } 628 629 __gmpfr_flags = oldflags; /* restore the flags */ 630 } /* tests in a reduced exponent range */ 631 632 if (MPFR_IS_SINGULAR (y)) 633 { 634 if (MPFR_IS_NAN (y) || mpfr_nanflag_p ()) 635 TGENERIC_CHECK ("bad NaN flag", 636 MPFR_IS_NAN (y) && mpfr_nanflag_p ()); 637 else if (MPFR_IS_INF (y)) 638 { 639 TGENERIC_CHECK ("bad overflow flag", 640 (compare != 0) ^ (mpfr_overflow_p () == 0)); 641 TGENERIC_CHECK ("bad divide-by-zero flag", 642 (compare == 0 && !infinite_input) ^ 643 (mpfr_divby0_p () == 0)); 644 } 645 else if (MPFR_IS_ZERO (y)) 646 TGENERIC_CHECK ("bad underflow flag", 647 (compare != 0) ^ (mpfr_underflow_p () == 0)); 648 } 649 else if (mpfr_divby0_p ()) 650 { 651 TGENERIC_CHECK ("both overflow and divide-by-zero", 652 ! mpfr_overflow_p ()); 653 TGENERIC_CHECK ("both underflow and divide-by-zero", 654 ! mpfr_underflow_p ()); 655 TGENERIC_CHECK ("bad compare value (divide-by-zero)", 656 compare == 0); 657 } 658 else if (mpfr_overflow_p ()) 659 { 660 TGENERIC_CHECK ("both underflow and overflow", 661 ! mpfr_underflow_p ()); 662 TGENERIC_CHECK ("bad compare value (overflow)", compare != 0); 663 mpfr_nexttoinf (y); 664 TGENERIC_CHECK ("should have been max MPFR number (overflow)", 665 MPFR_IS_INF (y)); 666 } 667 else if (mpfr_underflow_p ()) 668 { 669 TGENERIC_CHECK ("bad compare value (underflow)", compare != 0); 670 mpfr_nexttozero (y); 671 TGENERIC_CHECK ("should have been min MPFR number (underflow)", 672 MPFR_IS_ZERO (y)); 673 } 674 else if (compare == 0 || rnd == MPFR_RNDF || 675 mpfr_can_round (y, yprec, rnd, rnd, prec)) 676 { 677 ctrn++; 678 mpfr_set (t, y, rnd); 679 /* Risk of failures are known when some flags are already set 680 before the function call. Do not set the erange flag, as 681 it will remain set after the function call and no checks 682 are performed in such a case (see the mpfr_erangeflag_p 683 test below). */ 684 if (randlimb () & 1) 685 __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE; 686 #ifdef MPFR_DEBUG_TGENERIC 687 TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z)); 688 #endif 689 /* Let's increase the precision of the inputs in a random way. 690 In most cases, this doesn't make any difference, but for 691 the mpfr_fmod bug fixed in r6230, this triggers the bug. */ 692 mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15), 693 MPFR_RNDN); 694 #if defined(TWO_ARGS) 695 mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15), 696 MPFR_RNDN); 697 inexact = TEST_FUNCTION (z, x, u, rnd); 698 #elif defined(DOUBLE_ARG1) 699 inexact = TEST_FUNCTION (z, d, x, rnd); 700 #elif defined(DOUBLE_ARG2) 701 inexact = TEST_FUNCTION (z, x, d, rnd); 702 #elif defined(ULONG_ARG1) && defined(ONE_ARG) 703 inexact = TEST_FUNCTION (z, i, rnd); 704 #elif defined(ULONG_ARG1) 705 inexact = TEST_FUNCTION (z, i, x, rnd); 706 #elif defined(ULONG_ARG2) 707 inexact = TEST_FUNCTION (z, x, i, rnd); 708 #else 709 inexact = TEST_FUNCTION (z, x, rnd); 710 #endif 711 if (mpfr_erangeflag_p ()) 712 goto next_n; 713 if (! mpfr_equal_p (t, z) && rnd != MPFR_RNDF) 714 { 715 printf ("tgeneric: results differ for " 716 MAKE_STR(TEST_FUNCTION) " on\n x = "); 717 mpfr_dump (x); 718 #ifdef NEED_U 719 printf (" u = "); 720 mpfr_dump (u); 721 #endif 722 printf (" prec = %u, rnd_mode = %s\n", 723 (unsigned int) prec, mpfr_print_rnd_mode (rnd)); 724 printf ("Got "); 725 mpfr_dump (z); 726 printf ("Expected "); 727 mpfr_dump (t); 728 printf ("Approx "); 729 mpfr_dump (y); 730 exit (1); 731 } 732 compare2 = mpfr_cmp (t, y); 733 /* if rounding to nearest, cannot know the sign of t - f(x) 734 because of composed rounding: y = o(f(x)) and t = o(y) */ 735 if (compare * compare2 >= 0) 736 compare = compare + compare2; 737 else 738 compare = inexact; /* cannot determine sign(t-f(x)) */ 739 if (! SAME_SIGN (inexact, compare) && rnd != MPFR_RNDF) 740 { 741 printf ("Wrong inexact flag for rnd=%s: expected %d, got %d" 742 "\n", mpfr_print_rnd_mode (rnd), compare, inexact); 743 printf ("x = "); 744 mpfr_dump (x); 745 #ifdef NEED_U 746 printf ("u = "); 747 mpfr_dump (u); 748 #endif 749 printf ("y = "); 750 mpfr_dump (y); 751 printf ("t = "); 752 mpfr_dump (t); 753 exit (1); 754 } 755 } 756 else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL) 757 { 758 /* For developers only! */ 759 MPFR_ASSERTN (MPFR_IS_PURE_FP (y)); 760 mpfr_nexttoinf (y); 761 if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y)) 762 && !mpfr_overflow_p () && TGENERIC_SO_TEST) 763 { 764 printf ("Possible bug! |y| is the maximum finite number " 765 "and has been obtained when\nrounding toward zero" 766 " (%s). Thus there is a very probable overflow,\n" 767 "but the overflow flag is not set!\n", 768 mpfr_print_rnd_mode (rnd)); 769 printf ("x = "); 770 mpfr_dump (x); 771 #ifdef NEED_U 772 printf ("u = "); 773 mpfr_dump (u); 774 #endif 775 exit (1); 776 } 777 } 778 779 next_n: 780 /* In case the exponent range has been changed by 781 tests_default_random() or for special values... */ 782 mpfr_set_emin (old_emin); 783 mpfr_set_emax (old_emax); 784 } 785 } 786 787 #ifndef TGENERIC_NOWARNING 788 if (3 * ctrn < 2 * ctrt) 789 printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n", 790 ctrn, ctrt); 791 #endif 792 793 mpfr_clears (x, y, yd, yu, z, t, w, (mpfr_ptr) 0); 794 #ifdef NEED_U 795 mpfr_clear (u); 796 #endif 797 } 798 799 #undef TEST_RANDOM_POS 800 #undef TEST_RANDOM_POS2 801 #undef TEST_RANDOM_EMIN 802 #undef TEST_RANDOM_EMAX 803 #undef TEST_RANDOM_ALWAYS_SCALE 804 #undef RAND_FUNCTION 805 #undef TWO_ARGS 806 #undef TWO_ARGS_ALL 807 #undef NEED_U 808 #undef DOUBLE_ARG1 809 #undef DOUBLE_ARG2 810 #undef ULONG_ARG1 811 #undef ULONG_ARG2 812 #undef TEST_FUNCTION 813 #undef test_generic 814 #undef NSPEC 815