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