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