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