blob: 59d85269928bcbf0003d78209ea1669f67b33a92 [file] [log] [blame]
Austin Schuhbb1338c2024-06-15 19:31:16 -07001/* test mpz_congruent_p and mpz_congruent_ui_p
2
3Copyright 2001, 2002, 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 <stdio.h>
21#include <stdlib.h>
22#include "gmp-impl.h"
23#include "tests.h"
24
25
26void
27check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
28{
29 int got;
30 int swap;
31
32 for (swap = 0; swap <= 1; swap++)
33 {
34 got = (mpz_congruent_p (a, c, d) != 0);
35 if (want != got)
36 {
37 printf ("mpz_congruent_p wrong\n");
38 printf (" expected %d got %d\n", want, got);
39 mpz_trace (" a", a);
40 mpz_trace (" c", c);
41 mpz_trace (" d", d);
42 mp_trace_base = -16;
43 mpz_trace (" a", a);
44 mpz_trace (" c", c);
45 mpz_trace (" d", d);
46 abort ();
47 }
48
49 if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
50 {
51 unsigned long uc = mpz_get_ui (c);
52 unsigned long ud = mpz_get_ui (d);
53 got = (mpz_congruent_ui_p (a, uc, ud) != 0);
54 if (want != got)
55 {
56 printf ("mpz_congruent_ui_p wrong\n");
57 printf (" expected %d got %d\n", want, got);
58 mpz_trace (" a", a);
59 printf (" c=%lu\n", uc);
60 printf (" d=%lu\n", ud);
61 mp_trace_base = -16;
62 mpz_trace (" a", a);
63 printf (" c=0x%lX\n", uc);
64 printf (" d=0x%lX\n", ud);
65 abort ();
66 }
67 }
68
69 MPZ_SRCPTR_SWAP (a, c);
70 }
71}
72
73
74void
75check_data (void)
76{
77 static const struct {
78 const char *a;
79 const char *c;
80 const char *d;
81 int want;
82
83 } data[] = {
84
85 /* strict equality mod 0 */
86 { "0", "0", "0", 1 },
87 { "11", "11", "0", 1 },
88 { "3", "11", "0", 0 },
89
90 /* anything congruent mod 1 */
91 { "0", "0", "1", 1 },
92 { "1", "0", "1", 1 },
93 { "0", "1", "1", 1 },
94 { "123", "456", "1", 1 },
95 { "0x123456789123456789", "0x987654321987654321", "1", 1 },
96
97 /* csize==1, dsize==2 changing to 1 after stripping 2s */
98 { "0x3333333333333333", "0x33333333",
99 "0x180000000", 1 },
100 { "0x33333333333333333333333333333333", "0x3333333333333333",
101 "0x18000000000000000", 1 },
102
103 /* another dsize==2 becoming 1, with opposite signs this time */
104 { "0x444444441",
105 "-0x22222221F",
106 "0x333333330", 1 },
107 { "0x44444444444444441",
108 "-0x2222222222222221F",
109 "0x33333333333333330", 1 },
110 };
111
112 mpz_t a, c, d;
113 int i;
114
115 mpz_init (a);
116 mpz_init (c);
117 mpz_init (d);
118
119 for (i = 0; i < numberof (data); i++)
120 {
121 mpz_set_str_or_abort (a, data[i].a, 0);
122 mpz_set_str_or_abort (c, data[i].c, 0);
123 mpz_set_str_or_abort (d, data[i].d, 0);
124 check_one (a, c, d, data[i].want);
125 }
126
127 mpz_clear (a);
128 mpz_clear (c);
129 mpz_clear (d);
130}
131
132
133void
134check_random (int argc, char *argv[])
135{
136 gmp_randstate_ptr rands = RANDS;
137 mpz_t a, c, d, ra, rc;
138 int i;
139 int want;
140 int reps = 10000;
141 mpz_t bs;
142 unsigned long size_range, size;
143
144 if (argc >= 2)
145 reps = atoi (argv[1]);
146
147 mpz_init (bs);
148
149 mpz_init (a);
150 mpz_init (c);
151 mpz_init (d);
152 mpz_init (ra);
153 mpz_init (rc);
154
155 for (i = 0; i < reps; i++)
156 {
157 mpz_urandomb (bs, rands, 32);
158 size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
159
160 mpz_urandomb (bs, rands, size_range);
161 size = mpz_get_ui (bs);
162 mpz_rrandomb (a, rands, size);
163
164 mpz_urandomb (bs, rands, 32);
165 size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
166
167 mpz_urandomb (bs, rands, size_range);
168 size = mpz_get_ui (bs);
169 mpz_rrandomb (c, rands, size);
170
171 do
172 {
173 mpz_urandomb (bs, rands, 32);
174 size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
175
176 mpz_urandomb (bs, rands, size_range);
177 size = mpz_get_ui (bs);
178 mpz_rrandomb (d, rands, size);
179 }
180 while (SIZ(d) == 0);
181
182 mpz_negrandom (a, rands);
183 MPZ_CHECK_FORMAT (a);
184 mpz_negrandom (c, rands);
185 MPZ_CHECK_FORMAT (c);
186 mpz_negrandom (d, rands);
187
188 mpz_fdiv_r (ra, a, d);
189 mpz_fdiv_r (rc, c, d);
190
191 want = (mpz_cmp (ra, rc) == 0);
192 check_one (a, c, d, want);
193
194 mpz_sub (ra, ra, rc);
195 mpz_sub (a, a, ra);
196 MPZ_CHECK_FORMAT (a);
197 check_one (a, c, d, 1);
198
199 if (! mpz_pow2abs_p (d))
200 {
201 refmpz_combit (a, urandom() % (8*GMP_LIMB_BITS));
202 check_one (a, c, d, 0);
203 }
204 }
205
206 mpz_clear (bs);
207
208 mpz_clear (a);
209 mpz_clear (c);
210 mpz_clear (d);
211 mpz_clear (ra);
212 mpz_clear (rc);
213}
214
215
216int
217main (int argc, char *argv[])
218{
219 tests_start ();
220
221 check_data ();
222 check_random (argc, argv);
223
224 tests_end ();
225 exit (0);
226}