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