xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-cong_2exp.c (revision 230b95665bbd3a9d1a53658a36b1053f8382a519)
1 /* test mpz_congruent_2exp_p */
2 
3 /*
4 Copyright 2001 Free Software Foundation, Inc.
5 
6 This file is part of the GNU MP Library test suite.
7 
8 The GNU MP Library test suite is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 3 of the License,
11 or (at your option) any later version.
12 
13 The GNU MP Library test suite is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16 Public License for more details.
17 
18 You should have received a copy of the GNU General Public License along with
19 the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "gmp.h"
24 #include "gmp-impl.h"
25 #include "tests.h"
26 
27 
28 void
29 check_one (mpz_srcptr a, mpz_srcptr c, unsigned long d, int want)
30 {
31   mpz_t  diff, d2exp;
32   int    got;
33   int    swap;
34 
35   for (swap = 0; swap <= 1; swap++)
36     {
37       got = (mpz_congruent_2exp_p (a, c, d) != 0);
38       if (want != got)
39         {
40           mpz_init (diff);
41           mpz_init (d2exp);
42 
43           mpz_sub (diff, a, c);
44           mpz_set_ui (d2exp, 1L);
45           mpz_mul_2exp (d2exp, d2exp, d);
46 
47           printf ("mpz_congruent_2exp_p wrong\n");
48           printf ("   expected %d got %d\n", want, got);
49           mpz_trace ("   a", a);
50           mpz_trace ("   c", c);
51           mpz_trace (" a-c", diff);
52           mpz_trace (" 2^d", d2exp);
53           printf    ("   d=%lu\n", d);
54 
55           mp_trace_base = -16;
56           mpz_trace ("   a", a);
57           mpz_trace ("   c", c);
58           mpz_trace (" a-c", diff);
59           mpz_trace (" 2^d", d2exp);
60           printf    ("   d=0x%lX\n", d);
61           abort ();
62         }
63 
64       MPZ_SRCPTR_SWAP (a, c);
65     }
66 }
67 
68 
69 void
70 check_data (void)
71 {
72   static const struct {
73     const char     *a;
74     const char     *c;
75     unsigned long  d;
76     int            want;
77 
78   } data[] = {
79 
80     /* anything is congruent mod 1 */
81     { "0", "0", 0, 1 },
82     { "1", "0", 0, 1 },
83     { "0", "1", 0, 1 },
84     { "123", "456", 0, 1 },
85     { "0x123456789123456789", "0x987654321987654321", 0, 1 },
86 
87   };
88 
89   mpz_t   a, c;
90   int     i;
91 
92   mpz_init (a);
93   mpz_init (c);
94 
95   for (i = 0; i < numberof (data); i++)
96     {
97       mpz_set_str_or_abort (a, data[i].a, 0);
98       mpz_set_str_or_abort (c, data[i].c, 0);
99       check_one (a, c, data[i].d, data[i].want);
100     }
101 
102   mpz_clear (a);
103   mpz_clear (c);
104 }
105 
106 
107 void
108 check_random (int argc, char *argv[])
109 {
110   gmp_randstate_ptr rands = RANDS;
111   unsigned long  d;
112   mpz_t  a, c, ra, rc;
113   int    i;
114   int    want;
115   int    reps = 5000;
116 
117   if (argc >= 2)
118     reps = atoi (argv[1]);
119 
120   mpz_init (a);
121   mpz_init (c);
122   mpz_init (ra);
123   mpz_init (rc);
124 
125   for (i = 0; i < reps; i++)
126     {
127       mpz_errandomb (a, rands, 8*GMP_LIMB_BITS);
128       mpz_errandomb (c, rands, 8*GMP_LIMB_BITS);
129       d = urandom() % (8*GMP_LIMB_BITS);
130 
131       mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS));
132       mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS));
133 
134       mpz_negrandom (a, rands);
135       mpz_negrandom (c, rands);
136 
137       mpz_fdiv_r_2exp (ra, a, d);
138       mpz_fdiv_r_2exp (rc, c, d);
139 
140       want = (mpz_cmp (ra, rc) == 0);
141       check_one (a, c, d, want);
142 
143       mpz_sub (ra, ra, rc);
144       mpz_sub (a, a, ra);
145       check_one (a, c, d, 1);
146     }
147 
148   mpz_clear (a);
149   mpz_clear (c);
150   mpz_clear (ra);
151   mpz_clear (rc);
152 }
153 
154 
155 int
156 main (int argc, char *argv[])
157 {
158   tests_start ();
159 
160   check_data ();
161   check_random (argc, argv);
162 
163   tests_end ();
164   exit (0);
165 }
166