xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/t-cong_2exp.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
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.
7 
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library.  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