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