xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-cong.c (revision b757af438b42b93f8c6571f026d8b8ef3eaf5fc9)
1 /* test mpz_congruent_p and mpz_congruent_ui_p
2 
3 Copyright 2001, 2002 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library.
6 
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "gmp.h"
23 #include "gmp-impl.h"
24 #include "tests.h"
25 
26 
27 void
28 check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
29 {
30   int   got;
31   int   swap;
32 
33   for (swap = 0; swap <= 1; swap++)
34     {
35       got = (mpz_congruent_p (a, c, d) != 0);
36       if (want != got)
37         {
38           printf ("mpz_congruent_p wrong\n");
39           printf ("   expected %d got %d\n", want, got);
40           mpz_trace ("   a", a);
41           mpz_trace ("   c", c);
42           mpz_trace ("   d", d);
43           mp_trace_base = -16;
44           mpz_trace ("   a", a);
45           mpz_trace ("   c", c);
46           mpz_trace ("   d", d);
47           abort ();
48         }
49 
50       if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
51         {
52           unsigned long  uc = mpz_get_ui (c);
53           unsigned long  ud = mpz_get_ui (d);
54           got = (mpz_congruent_ui_p (a, uc, ud) != 0);
55           if (want != got)
56             {
57               printf    ("mpz_congruent_ui_p wrong\n");
58               printf    ("   expected %d got %d\n", want, got);
59               mpz_trace ("   a", a);
60               printf    ("   c=%lu\n", uc);
61               printf    ("   d=%lu\n", ud);
62               mp_trace_base = -16;
63               mpz_trace ("   a", a);
64               printf    ("   c=0x%lX\n", uc);
65               printf    ("   d=0x%lX\n", ud);
66               abort ();
67             }
68         }
69 
70       MPZ_SRCPTR_SWAP (a, c);
71     }
72 }
73 
74 
75 void
76 check_data (void)
77 {
78   static const struct {
79     const char *a;
80     const char *c;
81     const char *d;
82     int        want;
83 
84   } data[] = {
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   int     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
130 check_random (int argc, char *argv[])
131 {
132   gmp_randstate_ptr rands = RANDS;
133   mpz_t   a, c, d, ra, rc;
134   int     i;
135   int     want;
136   int     reps = 50000;
137 
138   if (argc >= 2)
139     reps = atoi (argv[1]);
140 
141   mpz_init (a);
142   mpz_init (c);
143   mpz_init (d);
144   mpz_init (ra);
145   mpz_init (rc);
146 
147   for (i = 0; i < reps; i++)
148     {
149       mpz_errandomb (a, rands, 8*GMP_LIMB_BITS);
150       MPZ_CHECK_FORMAT (a);
151       mpz_errandomb (c, rands, 8*GMP_LIMB_BITS);
152       MPZ_CHECK_FORMAT (c);
153       mpz_errandomb_nonzero (d, rands, 8*GMP_LIMB_BITS);
154 
155       mpz_negrandom (a, rands);
156       MPZ_CHECK_FORMAT (a);
157       mpz_negrandom (c, rands);
158       MPZ_CHECK_FORMAT (c);
159       mpz_negrandom (d, rands);
160 
161       mpz_fdiv_r (ra, a, d);
162       mpz_fdiv_r (rc, c, d);
163 
164       want = (mpz_cmp (ra, rc) == 0);
165       check_one (a, c, d, want);
166 
167       mpz_sub (ra, ra, rc);
168       mpz_sub (a, a, ra);
169       MPZ_CHECK_FORMAT (a);
170       check_one (a, c, d, 1);
171 
172       if (! mpz_pow2abs_p (d))
173         {
174           refmpz_combit (a, urandom() % (8*GMP_LIMB_BITS));
175           check_one (a, c, d, 0);
176         }
177     }
178 
179   mpz_clear (a);
180   mpz_clear (c);
181   mpz_clear (d);
182   mpz_clear (ra);
183   mpz_clear (rc);
184 }
185 
186 
187 int
188 main (int argc, char *argv[])
189 {
190   tests_start ();
191 
192   check_data ();
193   check_random (argc, argv);
194 
195   tests_end ();
196   exit (0);
197 }
198