Upload Tizen:Base source
[external/gmp.git] / tests / mpz / reuse.c
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 Free Software Foundation, Inc.
10
11 This file is part of the GNU MP Library.
12
13 The GNU MP Library is free software; you can redistribute it and/or modify
14 it under the terms of the GNU Lesser General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or (at your
16 option) any later version.
17
18 The GNU MP Library is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
21 License for more details.
22
23 You should have received a copy of the GNU Lesser General Public License
24 along 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
41 int
42 main (void)
43 {
44   printf ("Test suppressed for windows DLL\n");
45   exit (0);
46 }
47
48
49 #else /* ! DLL_EXPORT */
50
51 void dump __GMP_PROTO ((char *, mpz_t, mpz_t, mpz_t));
52
53 typedef void (*dss_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
54 typedef void (*dsi_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
55 typedef unsigned long int (*dsi_div_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
56 typedef unsigned long int (*ddsi_div_func) __GMP_PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
57 typedef void (*ddss_div_func) __GMP_PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
58 typedef void (*ds_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr));
59
60
61 void
62 mpz_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
70 dss_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 };
77 char *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 };
84 char dss_func_division[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
85
86 dsi_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 };
96 char *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
106 dsi_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 };
112 char *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
119 ddsi_div_func ddsi_div_funcs[] =
120 {
121   mpz_cdiv_qr_ui,
122   mpz_fdiv_qr_ui,
123   mpz_tdiv_qr_ui
124 };
125 char *ddsi_div_func_names[] =
126 {
127   "mpz_cdiv_qr_ui",
128   "mpz_fdiv_qr_ui",
129   "mpz_tdiv_qr_ui"
130 };
131
132 ddss_div_func ddss_div_funcs[] =
133 {
134   mpz_cdiv_qr,
135   mpz_fdiv_qr,
136   mpz_tdiv_qr
137 };
138 char *ddss_div_func_names[] =
139 {
140   "mpz_cdiv_qr",
141   "mpz_fdiv_qr",
142   "mpz_tdiv_qr"
143 };
144
145 ds_func ds_funcs[] =
146 {
147   mpz_abs, mpz_com, mpz_neg, mpz_sqrt
148 };
149 char *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
184 int
185 main (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
673 void
674 dump (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 */