blob: aaa31886221bffad1aed1b5abd2bc5667128de89 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/* Test mpz_add, mpz_sub, mpz_add_ui, mpz_sub_ui, and mpz_ui_sub.
2
3Copyright 2002 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 <stdio.h>
21#include <stdlib.h>
22
23#include "gmp-impl.h"
24#include "longlong.h"
25#include "tests.h"
26
27void debug_mp (mpz_t, int);
28void dump_abort (int, const char *, mpz_t, mpz_t);
29
30int
31main (int argc, char **argv)
32{
33 mpz_t op1, op2, r1, r2;
34 mp_size_t op1n, op2n;
35 unsigned long int op2long;
36 int i;
37 int reps = 100000;
38 gmp_randstate_ptr rands;
39 mpz_t bs;
40 unsigned long bsi, size_range;
41
42 tests_start ();
43 rands = RANDS;
44
45 mpz_init (bs);
46
47 if (argc == 2)
48 reps = atoi (argv[1]);
49
50 mpz_init (op1);
51 mpz_init (op2);
52 mpz_init (r1);
53 mpz_init (r2);
54
55 for (i = 0; i < reps; i++)
56 {
57 mpz_urandomb (bs, rands, 32);
58 size_range = mpz_get_ui (bs) % 10 + 2;
59
60 mpz_urandomb (bs, rands, size_range);
61 op1n = mpz_get_ui (bs);
62 mpz_rrandomb (op1, rands, op1n);
63
64 mpz_urandomb (bs, rands, size_range);
65 op2n = mpz_get_ui (bs);
66 mpz_rrandomb (op2, rands, op2n);
67
68 mpz_urandomb (bs, rands, 2);
69 bsi = mpz_get_ui (bs);
70 if ((bsi & 1) != 0)
71 mpz_neg (op1, op1);
72 if ((bsi & 2) != 0)
73 mpz_neg (op2, op2);
74
75 /* printf ("%ld %ld\n", SIZ (multiplier), SIZ (multiplicand)); */
76
77 mpz_add (r1, op1, op2);
78 mpz_sub (r2, r1, op2);
79 if (mpz_cmp (r2, op1) != 0)
80 dump_abort (i, "mpz_add or mpz_sub incorrect", op1, op2);
81
82 if (mpz_fits_ulong_p (op2))
83 {
84 op2long = mpz_get_ui (op2);
85 mpz_add_ui (r1, op1, op2long);
86 mpz_sub_ui (r2, r1, op2long);
87 if (mpz_cmp (r2, op1) != 0)
88 dump_abort (i, "mpz_add_ui or mpz_sub_ui incorrect", op1, op2);
89
90 mpz_ui_sub (r1, op2long, op1);
91 mpz_sub_ui (r2, op1, op2long);
92 mpz_neg (r2, r2);
93 if (mpz_cmp (r1, r2) != 0)
94 dump_abort (i, "mpz_add_ui or mpz_ui_sub incorrect", op1, op2);
95 }
96 }
97
98 mpz_clear (bs);
99 mpz_clear (op1);
100 mpz_clear (op2);
101 mpz_clear (r1);
102 mpz_clear (r2);
103
104 tests_end ();
105 exit (0);
106}
107
108void
109dump_abort (int i, const char *s, mpz_t op1, mpz_t op2)
110{
111 fprintf (stderr, "ERROR: %s in test %d\n", s, i);
112 fprintf (stderr, "op1 = "); debug_mp (op1, -16);
113 fprintf (stderr, "op2 = "); debug_mp (op2, -16);
114 abort();
115}
116
117void
118debug_mp (mpz_t x, int base)
119{
120 mpz_out_str (stderr, base, x); fputc ('\n', stderr);
121}