1 /* test mpz_congruent_p and mpz_congruent_ui_p
2
3 Copyright 2001, 2002, 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 <stdio.h>
21 #include <stdlib.h>
22 #include "gmp-impl.h"
23 #include "tests.h"
24
25
26 void
check_one(mpz_srcptr a,mpz_srcptr c,mpz_srcptr d,int want)27 check_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
74 void
check_data(void)75 check_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
133 void
check_random(int argc,char * argv[])134 check_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
216 int
main(int argc,char * argv[])217 main (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 }
227