1 /* test mpz_congruent_p
2
3 Copyright 2001, 2002, 2012, 2014 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 "testutils.h"
21
22 #define MPZ_SRCPTR_SWAP(x, y) \
23 do { \
24 mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
25 (x) = (y); \
26 (y) = __mpz_srcptr_swap__tmp; \
27 } while (0)
28
29 void
check_one(mpz_srcptr a,mpz_srcptr c,mpz_srcptr d,int want)30 check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
31 {
32 int got;
33 int swap;
34
35 for (swap = 0; swap <= 1; swap++)
36 {
37 got = (mpz_congruent_p (a, c, d) != 0);
38 if (want != got)
39 {
40 printf ("mpz_congruent_p wrong\n");
41 printf (" expected %d got %d\n", want, got);
42 dump (" a", a);
43 dump (" c", c);
44 dump (" d", d);
45 abort ();
46 }
47
48 #if 0
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 dump (" a", a);
59 printf (" c=%lu\n", uc);
60 printf (" d=%lu\n", ud);
61 abort ();
62 }
63 }
64 #endif
65 MPZ_SRCPTR_SWAP (a, c);
66 }
67 }
68
69
70 void
check_data(void)71 check_data (void)
72 {
73 static const struct {
74 const char *a;
75 const char *c;
76 const char *d;
77 int want;
78
79 } data[] = {
80
81 /* strict equality mod 0 */
82 { "0", "0", "0", 1 },
83 { "11", "11", "0", 1 },
84 { "3", "11", "0", 0 },
85
86 /* anything congruent mod 1 */
87 { "0", "0", "1", 1 },
88 { "1", "0", "1", 1 },
89 { "0", "1", "1", 1 },
90 { "123", "456", "1", 1 },
91 { "0x123456789123456789", "0x987654321987654321", "1", 1 },
92
93 /* csize==1, dsize==2 changing to 1 after stripping 2s */
94 { "0x3333333333333333", "0x33333333",
95 "0x180000000", 1 },
96 { "0x33333333333333333333333333333333", "0x3333333333333333",
97 "0x18000000000000000", 1 },
98
99 /* another dsize==2 becoming 1, with opposite signs this time */
100 { "0x444444441",
101 "-0x22222221F",
102 "0x333333330", 1 },
103 { "0x44444444444444441",
104 "-0x2222222222222221F",
105 "0x33333333333333330", 1 },
106 };
107
108 mpz_t a, c, d;
109 unsigned i;
110
111 mpz_init (a);
112 mpz_init (c);
113 mpz_init (d);
114
115 for (i = 0; i < numberof (data); i++)
116 {
117 mpz_set_str_or_abort (a, data[i].a, 0);
118 mpz_set_str_or_abort (c, data[i].c, 0);
119 mpz_set_str_or_abort (d, data[i].d, 0);
120 check_one (a, c, d, data[i].want);
121 }
122
123 mpz_clear (a);
124 mpz_clear (c);
125 mpz_clear (d);
126 }
127
128
129 void
check_random(int argc,char * argv[])130 check_random (int argc, char *argv[])
131 {
132 mpz_t a, c, d, ra, rc;
133 int i;
134 int want;
135 int reps = 10000;
136 mpz_t bs;
137 unsigned long size_range, size;
138
139 if (argc >= 2)
140 reps = atoi (argv[1]);
141
142 mpz_init (bs);
143
144 mpz_init (a);
145 mpz_init (c);
146 mpz_init (d);
147 mpz_init (ra);
148 mpz_init (rc);
149
150 for (i = 0; i < reps; i++)
151 {
152 mini_urandomb (bs, 32);
153 size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
154
155 mini_urandomb (bs, size_range);
156 size = mpz_get_ui (bs);
157 mini_rrandomb (a, size);
158
159 mini_urandomb (bs, 32);
160 size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
161
162 mini_urandomb (bs, size_range);
163 size = mpz_get_ui (bs);
164 mini_rrandomb (c, size);
165
166 do
167 {
168 mini_urandomb (bs, 32);
169 size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
170
171 mini_urandomb (bs, size_range);
172 size = mpz_get_ui (bs);
173 mini_rrandomb (d, size);
174 }
175 while (mpz_sgn(d) == 0);
176
177 mini_urandomb (bs, 3);
178 if (mpz_tstbit (bs, 0))
179 mpz_neg (a, a);
180 if (mpz_tstbit (bs, 1))
181 mpz_neg (c, c);
182 if (mpz_tstbit (bs, 2))
183 mpz_neg (d, d);
184
185 mpz_fdiv_r (ra, a, d);
186 mpz_fdiv_r (rc, c, d);
187
188 want = (mpz_cmp (ra, rc) == 0);
189 check_one (a, c, d, want);
190
191 mpz_sub (ra, ra, rc);
192 mpz_sub (a, a, ra);
193 check_one (a, c, d, 1);
194
195 }
196
197 mpz_clear (bs);
198
199 mpz_clear (a);
200 mpz_clear (c);
201 mpz_clear (d);
202 mpz_clear (ra);
203 mpz_clear (rc);
204 }
205
206
207 void
testmain(int argc,char * argv[])208 testmain (int argc, char *argv[])
209 {
210 check_data ();
211 check_random (argc, argv);
212 }
213