xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-cong.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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