blob: 5ac9e112db802b4eba9f793d930df71dfe2be9cd [file] [log] [blame]
Austin Schuhbb1338c2024-06-15 19:31:16 -07001/* Test that routines allow reusing a source variable as destination.
2
3Copyright 1996, 1999-2002, 2009, 2012 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the 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
28void dump3 (const char *, mpz_t, mpz_t, mpz_t);
29void mpz_check_format (const mpz_t);
30
31typedef void (*dss_func) (mpz_t, const mpz_t, const mpz_t);
32typedef void (*dsi_func) (mpz_t, const mpz_t, unsigned long int);
33typedef unsigned long int (*dsi_div_func) (mpz_t, const mpz_t, unsigned long int);
34typedef unsigned long int (*ddsi_div_func) (mpz_t, mpz_t, const mpz_t, unsigned long int);
35typedef void (*ddss_div_func) (mpz_t, mpz_t, const mpz_t, const mpz_t);
36typedef void (*ds_func) (mpz_t, const mpz_t);
37
38
39void
40mpz_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
48dss_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};
55const 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};
62char dss_func_division[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
63
64dsi_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};
74const 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
84dsi_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};
90const 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
97ddsi_div_func ddsi_div_funcs[] =
98{
99 mpz_cdiv_qr_ui,
100 mpz_fdiv_qr_ui,
101 mpz_tdiv_qr_ui
102};
103const char *ddsi_div_func_names[] =
104{
105 "mpz_cdiv_qr_ui",
106 "mpz_fdiv_qr_ui",
107 "mpz_tdiv_qr_ui"
108};
109
110ddss_div_func ddss_div_funcs[] =
111{
112 mpz_cdiv_qr,
113 mpz_fdiv_qr,
114 mpz_tdiv_qr
115};
116const char *ddss_div_func_names[] =
117{
118 "mpz_cdiv_qr",
119 "mpz_fdiv_qr",
120 "mpz_tdiv_qr"
121};
122
123ds_func ds_funcs[] =
124{
125 mpz_abs, mpz_com, mpz_neg, mpz_sqrt
126};
127const 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
145void
146testmain (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
627void
628dump3 (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
645void
646mpz_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}