1 /* Test that routines allow reusing a source variable as destination. 2 3 Test all relevant functions except: 4 mpz_bin_ui 5 mpz_nextprime 6 mpz_mul_si 7 mpz_addmul_ui (should this really allow a+=a*c?) 8 9 Copyright 1996, 1999-2002, 2009, 2012, 2013, 2016 Free Software Foundation, 10 Inc. 11 12 This file is part of the GNU MP Library test suite. 13 14 The GNU MP Library test suite is free software; you can redistribute it 15 and/or modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 3 of the License, 17 or (at your option) any later version. 18 19 The GNU MP Library test suite is distributed in the hope that it will be 20 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 22 Public License for more details. 23 24 You should have received a copy of the GNU General Public License along with 25 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 32 #include "gmp-impl.h" 33 #include "tests.h" 34 35 #if __GMP_LIBGMP_DLL 36 37 /* FIXME: When linking to a DLL libgmp, mpz_add etc can't be used as 38 initializers for global variables because they're effectively global 39 variables (function pointers) themselves. Perhaps calling a test 40 function successively with mpz_add etc would be better. */ 41 42 int 43 main (void) 44 { 45 printf ("Test suppressed for windows DLL\n"); 46 exit (0); 47 } 48 49 50 #else /* ! DLL_EXPORT */ 51 52 void dump (const char *, mpz_t, mpz_t, mpz_t); 53 54 typedef void (*dss_func) (mpz_ptr, mpz_srcptr, mpz_srcptr); 55 typedef void (*dsi_func) (mpz_ptr, mpz_srcptr, unsigned long int); 56 typedef unsigned long int (*dsi_div_func) (mpz_ptr, mpz_srcptr, unsigned long int); 57 typedef unsigned long int (*ddsi_div_func) (mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int); 58 typedef void (*ddss_div_func) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); 59 typedef void (*ds_func) (mpz_ptr, mpz_srcptr); 60 61 62 void 63 mpz_xinvert (mpz_ptr r, mpz_srcptr a, mpz_srcptr b) 64 { 65 int res; 66 res = mpz_invert (r, a, b); 67 if (res == 0) 68 mpz_set_ui (r, 0); 69 } 70 71 struct { 72 dss_func fptr; 73 const char *fname; 74 int isdivision; 75 int isslow; 76 } static dss[] = 77 { { mpz_add, "mpz_add", 0, 0 }, 78 { mpz_sub, "mpz_sub", 0, 0 }, 79 { mpz_mul, "mpz_mul", 0, 0 }, 80 { mpz_cdiv_q, "mpz_cdiv_q", 1, 0 }, 81 { mpz_cdiv_r, "mpz_cdiv_r", 1, 0 }, 82 { mpz_fdiv_q, "mpz_fdiv_q", 1, 0 }, 83 { mpz_fdiv_r, "mpz_fdiv_r", 1, 0 }, 84 { mpz_tdiv_q, "mpz_tdiv_q", 1, 0 }, 85 { mpz_tdiv_r, "mpz_tdiv_r", 1, 0 }, 86 { mpz_mod, "mpz_mod", 1, 0 }, 87 { mpz_xinvert, "mpz_xinvert", 1, 1 }, 88 { mpz_gcd, "mpz_gcd", 0, 1 }, 89 { mpz_lcm, "mpz_lcm", 0, 1 }, 90 { mpz_and, "mpz_and", 0, 0 }, 91 { mpz_ior, "mpz_ior", 0, 0 }, 92 { mpz_xor, "mpz_xor", 0, 0 } 93 }; 94 95 96 struct { 97 dsi_func fptr; 98 const char *fname; 99 int mod; 100 } static dsi[] = 101 { 102 /* Don't change order here without changing the code in main(). */ 103 { mpz_add_ui, "mpz_add_ui", 0 }, 104 { mpz_mul_ui, "mpz_mul_ui", 0 }, 105 { mpz_sub_ui, "mpz_sub_ui", 0 }, 106 { mpz_fdiv_q_2exp, "mpz_fdiv_q_2exp", 0x1000 }, 107 { mpz_fdiv_r_2exp, "mpz_fdiv_r_2exp", 0x1000 }, 108 { mpz_cdiv_q_2exp, "mpz_cdiv_q_2exp", 0x1000 }, 109 { mpz_cdiv_r_2exp, "mpz_cdiv_r_2exp", 0x1000 }, 110 { mpz_tdiv_q_2exp, "mpz_tdiv_q_2exp", 0x1000 }, 111 { mpz_tdiv_r_2exp, "mpz_tdiv_r_2exp", 0x1000 }, 112 { mpz_mul_2exp, "mpz_mul_2exp", 0x100 }, 113 { mpz_pow_ui, "mpz_pow_ui", 0x10 } 114 }; 115 116 struct { 117 dsi_div_func fptr; 118 const char *fname; 119 } static dsi_div[] = 120 { 121 { mpz_cdiv_q_ui, "mpz_cdiv_q_ui" }, 122 { mpz_cdiv_r_ui, "mpz_cdiv_r_ui" }, 123 { mpz_fdiv_q_ui, "mpz_fdiv_q_ui" }, 124 { mpz_fdiv_r_ui, "mpz_fdiv_r_ui" }, 125 { mpz_tdiv_q_ui, "mpz_tdiv_q_ui" }, 126 { mpz_tdiv_r_ui, "mpz_tdiv_r_ui" } 127 }; 128 129 struct { 130 ddsi_div_func fptr; 131 const char *fname; 132 int isslow; 133 } static ddsi_div[] = 134 { 135 { mpz_cdiv_qr_ui, "mpz_cdiv_qr_ui", 0 }, 136 { mpz_fdiv_qr_ui, "mpz_fdiv_qr_ui", 0 }, 137 { mpz_tdiv_qr_ui, "mpz_tdiv_qr_ui", 0 }, 138 }; 139 140 141 struct { 142 ddss_div_func fptr; 143 const char *fname; 144 int isslow; 145 } static ddss_div[] = 146 { 147 { mpz_cdiv_qr, "mpz_cdiv_qr", 0 }, 148 { mpz_fdiv_qr, "mpz_fdiv_qr", 0 }, 149 { mpz_tdiv_qr, "mpz_tdiv_qr", 0 }, 150 }; 151 152 struct { 153 ds_func fptr; 154 const char *fname; 155 int nonneg; 156 } static ds[] = 157 { 158 { mpz_abs, "mpz_abs", 0 }, 159 { mpz_com, "mpz_com", 0 }, 160 { mpz_neg, "mpz_neg", 0 }, 161 { mpz_sqrt, "mpz_sqrt", 1 }, 162 }; 163 164 #define FAIL(class,indx,op1,op2,op3) \ 165 do { \ 166 dump (class[indx].fname, op1, op2, op3); \ 167 exit (1); \ 168 } while (0) 169 170 #define FAIL2(fname,op1,op2,op3) \ 171 do { \ 172 dump (#fname, op1, op2, op3); \ 173 exit (1); \ 174 } while (0) 175 176 177 #define INVOKE_RRS(desc,r1,r2,i1) \ 178 do { \ 179 if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \ 180 if (pass & 2) _mpz_realloc (r2, ABSIZ(r2)); \ 181 (desc).fptr (r1, r2, i1); \ 182 } while (0) 183 #define INVOKE_RS(desc,r1,i1) \ 184 do { \ 185 if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \ 186 (desc).fptr (r1, i1); \ 187 } while (0) 188 #define INVOKE_RRSS(desc,r1,r2,i1,i2) \ 189 do { \ 190 if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \ 191 if (pass & 2) _mpz_realloc (r2, ABSIZ(r2)); \ 192 (desc).fptr (r1, r2, i1, i2); \ 193 } while (0) 194 #define INVOKE_RSS(desc,r1,i1,i2) \ 195 do { \ 196 if (pass & 1) _mpz_realloc (r1, ABSIZ(r1)); \ 197 (desc).fptr (r1, i1, i2); \ 198 } while (0) 199 200 int 201 main (int argc, char **argv) 202 { 203 int i; 204 unsigned int pass, reps = 400; 205 mpz_t in1, in2, in3; 206 unsigned long int in2i; 207 mp_size_t size; 208 mpz_t res1, res2, res3; 209 mpz_t ref1, ref2, ref3; 210 mpz_t t; 211 unsigned long int r1, r2; 212 gmp_randstate_ptr rands; 213 mpz_t bs; 214 unsigned long bsi, size_range; 215 216 tests_start (); 217 TESTS_REPS (reps, argv, argc); 218 219 rands = RANDS; 220 221 mpz_init (bs); 222 223 mpz_init (in1); 224 mpz_init (in2); 225 mpz_init (in3); 226 mpz_init (ref1); 227 mpz_init (ref2); 228 mpz_init (ref3); 229 mpz_init (res1); 230 mpz_init (res2); 231 mpz_init (res3); 232 mpz_init (t); 233 234 mpz_set_ui (res1, 1); /* force allocation */ 235 mpz_set_ui (res2, 1); /* force allocation */ 236 mpz_set_ui (res3, 1); /* force allocation */ 237 238 for (pass = 1; pass <= reps; pass++) 239 { 240 #ifndef VERBOSE 241 if (isatty (fileno (stdout))) 242 { 243 printf ("\r%d/%d passes", pass, reps); 244 fflush (stdout); 245 } 246 #endif 247 248 mpz_urandomb (bs, rands, 32); 249 /* Make size_range gradually bigger with each pass. */ 250 size_range = mpz_get_ui (bs) % (pass * 15 / reps + 1) + 8; 251 252 #define MAKE_RANDOM_OP(in, size_range, s) \ 253 do { \ 254 mpz_urandomb (bs, rands, size_range); \ 255 if (((pass >> s) & 3) == 3) /* conditional exponential dist */ \ 256 mpz_urandomb (bs, rands, mpz_get_ui (bs) % (size_range - 7) + 7); \ 257 mpz_rrandomb (in, rands, mpz_get_ui (bs)); \ 258 } while (0) 259 260 MAKE_RANDOM_OP (in1, size_range, 0); 261 MAKE_RANDOM_OP (in2, size_range, 2); 262 MAKE_RANDOM_OP (in3, size_range, 4); 263 #undef MAKE_RANDOM_OP 264 265 #ifdef VERBOSE 266 printf("%9d%9d%8d\n", 267 mpz_sizeinbase(in1,2), 268 mpz_sizeinbase(in2,2), 269 mpz_sizeinbase(in3,2)); 270 #endif 271 272 mpz_urandomb (bs, rands, 3); 273 bsi = mpz_get_ui (bs); 274 if ((bsi & 1) != 0) 275 mpz_neg (in1, in1); 276 if ((bsi & 2) != 0) 277 mpz_neg (in2, in2); 278 if ((bsi & 4) != 0) 279 mpz_neg (in3, in3); 280 281 for (i = 0; i < numberof (dss); i++) 282 { 283 if (dss[i].isdivision && mpz_sgn (in2) == 0) 284 continue; 285 if (dss[i].isslow && size_range > 19) 286 continue; 287 288 (dss[i].fptr) (ref1, in1, in2); 289 MPZ_CHECK_FORMAT (ref1); 290 291 mpz_set (res1, in1); 292 INVOKE_RSS (dss[i], res1, res1, in2); 293 MPZ_CHECK_FORMAT (res1); 294 if (mpz_cmp (ref1, res1) != 0) 295 FAIL (dss, i, in1, in2, NULL); 296 297 mpz_set (res1, in2); 298 INVOKE_RSS (dss[i], res1, in1, res1); 299 MPZ_CHECK_FORMAT (res1); 300 if (mpz_cmp (ref1, res1) != 0) 301 FAIL (dss, i, in1, in2, NULL); 302 } 303 304 for (i = 0; i < numberof (ddss_div); i++) 305 { 306 if (mpz_sgn (in2) == 0) 307 continue; 308 309 (ddss_div[i].fptr) (ref1, ref2, in1, in2); 310 MPZ_CHECK_FORMAT (ref1); 311 MPZ_CHECK_FORMAT (ref2); 312 313 mpz_set (res1, in1); 314 mpz_clobber (res2); 315 INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2); 316 MPZ_CHECK_FORMAT (res1); 317 MPZ_CHECK_FORMAT (res2); 318 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 319 FAIL (ddss_div, i, in1, in2, NULL); 320 321 mpz_clobber (res1); 322 mpz_set (res2, in1); 323 INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2); 324 MPZ_CHECK_FORMAT (res1); 325 MPZ_CHECK_FORMAT (res2); 326 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 327 FAIL (ddss_div, i, in1, in2, NULL); 328 329 mpz_set (res1, in2); 330 mpz_clobber (res2); 331 INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1); 332 MPZ_CHECK_FORMAT (res1); 333 MPZ_CHECK_FORMAT (res2); 334 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 335 FAIL (ddss_div, i, in1, in2, NULL); 336 337 mpz_clobber (res1); 338 mpz_set (res2, in2); 339 INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2); 340 MPZ_CHECK_FORMAT (res1); 341 MPZ_CHECK_FORMAT (res2); 342 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 343 FAIL (ddss_div, i, in1, in2, NULL); 344 } 345 346 for (i = 0; i < numberof (ds); i++) 347 { 348 if (ds[i].nonneg && mpz_sgn (in1) < 0) 349 continue; 350 351 (ds[i].fptr) (ref1, in1); 352 MPZ_CHECK_FORMAT (ref1); 353 354 mpz_set (res1, in1); 355 INVOKE_RS (ds[i], res1, res1); 356 MPZ_CHECK_FORMAT (res1); 357 if (mpz_cmp (ref1, res1) != 0) 358 FAIL (ds, i, in1, in2, NULL); 359 } 360 361 in2i = mpz_get_ui (in2); 362 363 for (i = 0; i < numberof (dsi); i++) 364 { 365 if (dsi[i].mod != 0) 366 in2i = mpz_get_ui (in2) % dsi[i].mod; 367 368 (dsi[i].fptr) (ref1, in1, in2i); 369 MPZ_CHECK_FORMAT (ref1); 370 371 mpz_set (res1, in1); 372 INVOKE_RRS (dsi[i], res1, res1, in2i); 373 MPZ_CHECK_FORMAT (res1); 374 if (mpz_cmp (ref1, res1) != 0) 375 FAIL (dsi, i, in1, in2, NULL); 376 } 377 378 if (in2i != 0) /* Don't divide by 0. */ 379 { 380 for (i = 0; i < numberof (dsi_div); i++) 381 { 382 r1 = (dsi_div[i].fptr) (ref1, in1, in2i); 383 MPZ_CHECK_FORMAT (ref1); 384 385 mpz_set (res1, in1); 386 r2 = (dsi_div[i].fptr) (res1, res1, in2i); 387 MPZ_CHECK_FORMAT (res1); 388 if (mpz_cmp (ref1, res1) != 0 || r1 != r2) 389 FAIL (dsi_div, i, in1, in2, NULL); 390 } 391 392 for (i = 0; i < numberof (ddsi_div); i++) 393 { 394 r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i); 395 MPZ_CHECK_FORMAT (ref1); 396 397 mpz_set (res1, in1); 398 mpz_clobber (res2); 399 r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i); 400 MPZ_CHECK_FORMAT (res1); 401 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2) 402 FAIL (ddsi_div, i, in1, in2, NULL); 403 404 mpz_clobber (res1); 405 mpz_set (res2, in1); 406 (ddsi_div[i].fptr) (res1, res2, res2, in2i); 407 MPZ_CHECK_FORMAT (res1); 408 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2) 409 FAIL (ddsi_div, i, in1, in2, NULL); 410 } 411 } 412 413 if (mpz_sgn (in1) >= 0) 414 { 415 mpz_sqrtrem (ref1, ref2, in1); 416 MPZ_CHECK_FORMAT (ref1); 417 MPZ_CHECK_FORMAT (ref2); 418 419 mpz_set (res1, in1); 420 mpz_sqrtrem (res1, res2, res1); 421 MPZ_CHECK_FORMAT (res1); 422 MPZ_CHECK_FORMAT (res2); 423 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 424 FAIL2 (mpz_sqrtrem, in1, NULL, NULL); 425 426 mpz_set (res2, in1); 427 mpz_sqrtrem (res1, res2, res2); 428 MPZ_CHECK_FORMAT (res1); 429 MPZ_CHECK_FORMAT (res2); 430 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 431 FAIL2 (mpz_sqrtrem, in1, NULL, NULL); 432 433 mpz_set (res1, in1); 434 mpz_sqrtrem (res1, res1, res1); 435 MPZ_CHECK_FORMAT (res1); 436 if (mpz_cmp (ref2, res1) != 0) 437 FAIL2 (mpz_sqrtrem, in1, NULL, NULL); 438 } 439 440 if (mpz_sgn (in1) >= 0) 441 { 442 mpz_root (ref1, in1, in2i % 0x100 + 1); 443 MPZ_CHECK_FORMAT (ref1); 444 445 mpz_set (res1, in1); 446 mpz_root (res1, res1, in2i % 0x100 + 1); 447 MPZ_CHECK_FORMAT (res1); 448 if (mpz_cmp (ref1, res1) != 0) 449 FAIL2 (mpz_root, in1, in2, NULL); 450 } 451 452 if (mpz_sgn (in1) >= 0) 453 { 454 mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1); 455 MPZ_CHECK_FORMAT (ref1); 456 MPZ_CHECK_FORMAT (ref2); 457 458 mpz_set (res1, in1); 459 mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1); 460 MPZ_CHECK_FORMAT (res1); 461 MPZ_CHECK_FORMAT (res2); 462 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 463 FAIL2 (mpz_rootrem, in1, in2, NULL); 464 465 mpz_set (res2, in1); 466 mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1); 467 MPZ_CHECK_FORMAT (res1); 468 MPZ_CHECK_FORMAT (res2); 469 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) 470 FAIL2 (mpz_rootrem, in1, in2, NULL); 471 } 472 473 if (size_range < 18) /* run fewer tests since gcdext is slow */ 474 { 475 mpz_gcdext (ref1, ref2, ref3, in1, in2); 476 MPZ_CHECK_FORMAT (ref1); 477 MPZ_CHECK_FORMAT (ref2); 478 MPZ_CHECK_FORMAT (ref3); 479 480 #define GCDEXT_CHECK3(i1, i2) do { \ 481 mpz_gcdext (res1, res2, res3, i1, i2); \ 482 MPZ_CHECK_FORMAT (res1); \ 483 MPZ_CHECK_FORMAT (res2); \ 484 MPZ_CHECK_FORMAT (res3); \ 485 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 \ 486 || mpz_cmp (ref3, res3) != 0) \ 487 FAIL2 (mpz_gcdext, i1, i2, NULL); \ 488 } while (0) 489 #define GCDEXT_CHECK2(i1, i2) do { \ 490 mpz_gcdext (res1, res2, NULL, i1, i2); \ 491 MPZ_CHECK_FORMAT (res1); \ 492 MPZ_CHECK_FORMAT (res2); \ 493 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) \ 494 FAIL2 (mpz_gcdext, i1, i2, NULL); \ 495 } while (0) 496 497 mpz_set (res1, in1); 498 mpz_clobber (res2); 499 mpz_clobber (res3); 500 GCDEXT_CHECK3 (res1, in2); 501 502 mpz_clobber (res1); 503 mpz_set (res2, in1); 504 mpz_clobber (res3); 505 GCDEXT_CHECK3 (res2, in2); 506 507 mpz_clobber (res1); 508 mpz_clobber (res2); 509 mpz_set (res3, in1); 510 GCDEXT_CHECK3 (res3, in2); 511 512 mpz_set (res1, in2); 513 mpz_clobber (res2); 514 mpz_clobber (res3); 515 GCDEXT_CHECK3 (in1, res1); 516 517 mpz_clobber (res1); 518 mpz_set (res2, in2); 519 mpz_clobber (res3); 520 GCDEXT_CHECK3 (in1, res2); 521 522 mpz_clobber (res1); 523 mpz_clobber (res2); 524 mpz_set (res3, in2); 525 GCDEXT_CHECK3 (in1, res3); 526 527 mpz_set (res1, in1); 528 mpz_set (res2, in2); 529 mpz_clobber (res3); 530 GCDEXT_CHECK3 (res1, res2); 531 532 mpz_set (res1, in1); 533 mpz_clobber (res2); 534 mpz_set (res3, in2); 535 GCDEXT_CHECK3 (res1, res3); 536 537 mpz_clobber (res1); 538 mpz_set (res2, in1); 539 mpz_set (res3, in2); 540 GCDEXT_CHECK3 (res2, res3); 541 542 mpz_set (res1, in2); 543 mpz_set (res2, in1); 544 mpz_clobber (res3); 545 GCDEXT_CHECK3 (res2, res1); 546 547 mpz_set (res1, in2); 548 mpz_clobber (res2); 549 mpz_set (res3, in1); 550 GCDEXT_CHECK3 (res3, res1); 551 552 mpz_clobber (res1); 553 mpz_set (res2, in2); 554 mpz_set (res3, in1); 555 GCDEXT_CHECK3(res3, res2); 556 557 mpz_set (res1, in1); 558 mpz_clobber (res2); 559 GCDEXT_CHECK2 (res1, in2); 560 561 mpz_clobber (res1); 562 mpz_set (res2, in1); 563 GCDEXT_CHECK2 (res2, in2); 564 565 mpz_set (res1, in2); 566 mpz_clobber (res2); 567 GCDEXT_CHECK2 (in1, res1); 568 569 mpz_clobber (res1); 570 mpz_set (res2, in2); 571 GCDEXT_CHECK2 (in1, res2); 572 #undef GCDEXT_CHECK 573 /* Identical inputs, gcd(in1, in1). Then the result should be 574 gcd = abs(in1), s = 0, t = sgn(in1). */ 575 mpz_abs (ref1, in1); 576 mpz_set_ui (ref2, 0); 577 mpz_set_si (ref3, mpz_sgn (in1)); 578 579 #define GCDEXT_CHECK_SAME3(in) do { \ 580 mpz_gcdext (res1, res2, res3, in, in); \ 581 MPZ_CHECK_FORMAT (res1); \ 582 MPZ_CHECK_FORMAT (res2); \ 583 MPZ_CHECK_FORMAT (res3); \ 584 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 \ 585 || mpz_cmp (ref3, res3) != 0) \ 586 FAIL2 (mpz_gcdext, in, in, NULL); \ 587 } while (0) 588 #define GCDEXT_CHECK_SAME2(in) do { \ 589 mpz_gcdext (res1, res2, NULL, in, in); \ 590 MPZ_CHECK_FORMAT (res1); \ 591 MPZ_CHECK_FORMAT (res2); \ 592 if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) \ 593 FAIL2 (mpz_gcdext, in, in, NULL); \ 594 } while (0) 595 596 mpz_set (res1, in1); 597 mpz_clobber (res2); 598 mpz_clobber (res3); 599 GCDEXT_CHECK_SAME3 (res1); 600 601 mpz_clobber (res1); 602 mpz_set (res2, in1); 603 mpz_clobber (res3); 604 GCDEXT_CHECK_SAME3 (res2); 605 606 mpz_clobber (res1); 607 mpz_clobber (res2); 608 mpz_set (res3, in1); 609 GCDEXT_CHECK_SAME3 (res3); 610 611 mpz_set (res1, in1); 612 mpz_clobber (res2); 613 mpz_clobber (res3); 614 GCDEXT_CHECK_SAME2 (res1); 615 616 mpz_clobber (res1); 617 mpz_set (res2, in1); 618 mpz_clobber (res3); 619 GCDEXT_CHECK_SAME2 (res2); 620 #undef GCDEXT_CHECK_SAME 621 } 622 623 /* Don't run mpz_powm for huge exponents or when undefined. */ 624 if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0 625 && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3))) 626 { 627 mpz_powm (ref1, in1, in2, in3); 628 MPZ_CHECK_FORMAT (ref1); 629 630 mpz_set (res1, in1); 631 mpz_powm (res1, res1, in2, in3); 632 MPZ_CHECK_FORMAT (res1); 633 if (mpz_cmp (ref1, res1) != 0) 634 FAIL2 (mpz_powm, in1, in2, in3); 635 636 mpz_set (res1, in2); 637 mpz_powm (res1, in1, res1, in3); 638 MPZ_CHECK_FORMAT (res1); 639 if (mpz_cmp (ref1, res1) != 0) 640 FAIL2 (mpz_powm, in1, in2, in3); 641 642 mpz_set (res1, in3); 643 mpz_powm (res1, in1, in2, res1); 644 MPZ_CHECK_FORMAT (res1); 645 if (mpz_cmp (ref1, res1) != 0) 646 FAIL2 (mpz_powm, in1, in2, in3); 647 } 648 649 /* Don't run mpz_powm_ui when undefined. */ 650 if (size_range < 17 && mpz_sgn (in3) != 0) 651 { 652 mpz_powm_ui (ref1, in1, in2i, in3); 653 MPZ_CHECK_FORMAT (ref1); 654 655 mpz_set (res1, in1); 656 mpz_powm_ui (res1, res1, in2i, in3); 657 MPZ_CHECK_FORMAT (res1); 658 if (mpz_cmp (ref1, res1) != 0) 659 FAIL2 (mpz_powm_ui, in1, in2, in3); 660 661 mpz_set (res1, in3); 662 mpz_powm_ui (res1, in1, in2i, res1); 663 MPZ_CHECK_FORMAT (res1); 664 if (mpz_cmp (ref1, res1) != 0) 665 FAIL2 (mpz_powm_ui, in1, in2, in3); 666 } 667 668 { 669 r1 = mpz_gcd_ui (ref1, in1, in2i); 670 MPZ_CHECK_FORMAT (ref1); 671 672 mpz_set (res1, in1); 673 r2 = mpz_gcd_ui (res1, res1, in2i); 674 MPZ_CHECK_FORMAT (res1); 675 if (mpz_cmp (ref1, res1) != 0) 676 FAIL2 (mpz_gcd_ui, in1, in2, NULL); 677 } 678 679 if (mpz_sgn (in2) != 0) 680 { 681 /* Test mpz_remove */ 682 mp_bitcnt_t refretval, retval; 683 refretval = mpz_remove (ref1, in1, in2); 684 MPZ_CHECK_FORMAT (ref1); 685 686 mpz_set (res1, in1); 687 retval = mpz_remove (res1, res1, in2); 688 MPZ_CHECK_FORMAT (res1); 689 if (mpz_cmp (ref1, res1) != 0 || refretval != retval) 690 FAIL2 (mpz_remove, in1, in2, NULL); 691 692 mpz_set (res1, in2); 693 retval = mpz_remove (res1, in1, res1); 694 MPZ_CHECK_FORMAT (res1); 695 if (mpz_cmp (ref1, res1) != 0 || refretval != retval) 696 FAIL2 (mpz_remove, in1, in2, NULL); 697 } 698 699 if (mpz_sgn (in2) != 0) 700 { 701 /* Test mpz_divexact */ 702 mpz_mul (t, in1, in2); 703 mpz_divexact (ref1, t, in2); 704 MPZ_CHECK_FORMAT (ref1); 705 706 mpz_set (res1, t); 707 mpz_divexact (res1, res1, in2); 708 MPZ_CHECK_FORMAT (res1); 709 if (mpz_cmp (ref1, res1) != 0) 710 FAIL2 (mpz_divexact, t, in2, NULL); 711 712 mpz_set (res1, in2); 713 mpz_divexact (res1, t, res1); 714 MPZ_CHECK_FORMAT (res1); 715 if (mpz_cmp (ref1, res1) != 0) 716 FAIL2 (mpz_divexact, t, in2, NULL); 717 } 718 719 if (mpz_sgn (in2) > 0) 720 { 721 /* Test mpz_divexact_gcd, same as mpz_divexact */ 722 mpz_mul (t, in1, in2); 723 mpz_divexact_gcd (ref1, t, in2); 724 MPZ_CHECK_FORMAT (ref1); 725 726 mpz_set (res1, t); 727 mpz_divexact_gcd (res1, res1, in2); 728 MPZ_CHECK_FORMAT (res1); 729 if (mpz_cmp (ref1, res1) != 0) 730 FAIL2 (mpz_divexact_gcd, t, in2, NULL); 731 732 mpz_set (res1, in2); 733 mpz_divexact_gcd (res1, t, res1); 734 MPZ_CHECK_FORMAT (res1); 735 if (mpz_cmp (ref1, res1) != 0) 736 FAIL2 (mpz_divexact_gcd, t, in2, NULL); 737 } 738 } 739 740 if (isatty (fileno (stdout))) 741 printf ("\r%20s", ""); 742 743 mpz_clear (bs); 744 mpz_clear (in1); 745 mpz_clear (in2); 746 mpz_clear (in3); 747 mpz_clear (ref1); 748 mpz_clear (ref2); 749 mpz_clear (ref3); 750 mpz_clear (res1); 751 mpz_clear (res2); 752 mpz_clear (res3); 753 mpz_clear (t); 754 755 if (isatty (fileno (stdout))) 756 printf ("\r"); 757 758 tests_end (); 759 exit (0); 760 } 761 762 void 763 dump (const char *name, mpz_t in1, mpz_t in2, mpz_t in3) 764 { 765 printf ("failure in %s (", name); 766 0 && mpz_out_str (stdout, -16, in1); 767 if (in2 != NULL) 768 { 769 printf (" "); 770 0 && mpz_out_str (stdout, -16, in2); 771 } 772 if (in3 != NULL) 773 { 774 printf (" "); 775 0 && mpz_out_str (stdout, -16, in3); 776 } 777 printf (")\n"); 778 } 779 780 #endif /* ! DLL_EXPORT */ 781