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