Tizen 2.1 base
[external/gmp.git] / tests / mpz / t-cong_2exp.c
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 }