xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/reuse.c (revision 37afb7eb6895c833050f8bfb1d1bb2f99f332539)
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