Upload Tizen:Base source
[external/gmp.git] / tests / mpz / t-cong.c
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 }