source: trunk/third/gmp/tests/mpz/bit.c @ 18191

Revision 18191, 5.8 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18190, which included commits to RCS files with non-trunk default branches.
Line 
1/* Test mpz_setbit, mpz_clrbit, mpz_tstbit.
2
3Copyright 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include <stdlib.h>
24
25#include "gmp.h"
26#include "gmp-impl.h"
27#include "tests.h"
28
29#ifndef SIZE
30#define SIZE 4
31#endif
32
33
34void
35debug_mp (mpz_srcptr x, int base)
36{
37  mpz_out_str (stdout, base, x); fputc ('\n', stdout);
38}
39
40
41/* See that mpz_tstbit matches a twos complement calculated explicitly, for
42   various low zeros.  */
43void
44check_tstbit (void)
45{
46#define MAX_ZEROS  3
47#define NUM_LIMBS  3
48
49  mp_limb_t      pos[1+NUM_LIMBS+MAX_ZEROS];
50  mp_limb_t      neg[1+NUM_LIMBS+MAX_ZEROS];
51  mpz_t          z;
52  unsigned long  i;
53  int            zeros, low1;
54  int            got, want;
55
56  mpz_init (z);
57  for (zeros = 0; zeros <= MAX_ZEROS; zeros++)
58    {
59      MPN_ZERO (pos, numberof(pos));
60      mpn_random2 (pos+zeros, NUM_LIMBS);
61
62      for (low1 = 0; low1 <= 1; low1++)
63        {
64          if (low1)
65            pos[0] |= 1;
66
67          refmpn_neg_n (neg, pos, numberof(neg));
68          mpz_set_n (z, neg, numberof(neg));
69          mpz_neg (z, z);
70
71          for (i = 0; i < numberof(pos)*GMP_NUMB_BITS; i++)
72            {
73              got = mpz_tstbit (z, i);
74              want = refmpn_tstbit (pos, i);
75              if (got != want)
76                {
77                  printf ("wrong at bit %lu, with %d zeros\n", i, zeros);
78                  printf ("z neg "); debug_mp (z, -16);
79                  mpz_set_n (z, pos, numberof(pos));
80                  printf ("pos   "); debug_mp (z, -16);
81                  mpz_set_n (z, neg, numberof(neg));
82                  printf ("neg   "); debug_mp (z, -16);
83                  exit (1);
84                }
85            }
86        }
87    }
88  mpz_clear (z);
89}
90
91
92void
93check_single (void)
94{
95  mpz_t  x;
96  int    limb, offset, initial;
97  unsigned long  bit;
98
99  mpz_init (x);
100
101  for (limb = 0; limb < 4; limb++)
102    {
103      for (offset = (limb==0 ? 0 : -2); offset <= 2; offset++)
104        {
105          for (initial = 0; initial >= -1; initial--)
106            {
107              mpz_set_si (x, (long) initial);
108
109              bit = (unsigned long) limb*BITS_PER_MP_LIMB + offset;
110
111              mpz_clrbit (x, bit);
112              MPZ_CHECK_FORMAT (x);
113              if (mpz_tstbit (x, bit) != 0)
114                {
115                  printf ("check_single(): expected 0\n");
116                  abort ();
117                }
118         
119              mpz_setbit (x, bit);
120              MPZ_CHECK_FORMAT (x);
121              if (mpz_tstbit (x, bit) != 1)
122                {
123                  printf ("check_single(): expected 0\n");
124                  abort ();
125                }
126         
127              mpz_clrbit (x, bit);
128              MPZ_CHECK_FORMAT (x);
129              if (mpz_tstbit (x, bit) != 0)
130                {
131                  printf ("check_single(): expected 0\n");
132                  abort ();
133                }
134            }
135        }
136    }         
137
138  mpz_clear (x);
139}
140
141
142void
143check_random (int argc, char *argv[])
144{
145  mpz_t x, s0, s1, s2, s3, m;
146  mp_size_t xsize;
147  int i;
148  int reps = 100000;
149  int bit0, bit1, bit2, bit3;
150  unsigned long int bitindex;
151  const char  *s = "";
152
153  if (argc == 2)
154    reps = atoi (argv[1]);
155
156  mpz_init (x);
157  mpz_init (s0);
158  mpz_init (s1);
159  mpz_init (s2);
160  mpz_init (s3);
161  mpz_init (m);
162
163  for (i = 0; i < reps; i++)
164    {
165      xsize = urandom () % (2 * SIZE) - SIZE;
166      mpz_random2 (x, xsize);
167      bitindex = urandom () % SIZE;
168
169      mpz_set (s0, x);
170      bit0 = mpz_tstbit (x, bitindex);
171      mpz_setbit (x, bitindex);
172      MPZ_CHECK_FORMAT (x);
173
174      mpz_set (s1, x);
175      bit1 = mpz_tstbit (x, bitindex);
176      mpz_clrbit (x, bitindex);
177      MPZ_CHECK_FORMAT (x);
178
179      mpz_set (s2, x);
180      bit2 = mpz_tstbit (x, bitindex);
181      mpz_setbit (x, bitindex);
182      MPZ_CHECK_FORMAT (x);
183
184      mpz_set (s3, x);
185      bit3 = mpz_tstbit (x, bitindex);
186
187#define FAIL(str) do { s = str; goto fail; } while (0)
188
189      if (bit1 != 1)  FAIL ("bit1 != 1");
190      if (bit2 != 0)  FAIL ("bit2 != 0");
191      if (bit3 != 1)  FAIL ("bit3 != 1");
192
193      if (bit0 == 0)
194        {
195          if (mpz_cmp (s0, s1) == 0 || mpz_cmp (s0, s2) != 0 || mpz_cmp (s0, s3) == 0)
196            abort ();
197        }
198      else
199        {
200          if (mpz_cmp (s0, s1) != 0 || mpz_cmp (s0, s2) == 0 || mpz_cmp (s0, s3) != 0)
201            abort ();
202        }
203
204      if (mpz_cmp (s1, s2) == 0 || mpz_cmp (s1, s3) != 0)
205        abort ();
206      if (mpz_cmp (s2, s3) == 0)
207        abort ();
208
209      mpz_ui_pow_ui (m, 2L, bitindex);
210      MPZ_CHECK_FORMAT (m);
211      mpz_ior (x, s2, m);
212      MPZ_CHECK_FORMAT (x);
213      if (mpz_cmp (x, s3) != 0)
214        abort ();
215
216      mpz_com (m, m);
217      MPZ_CHECK_FORMAT (m);
218      mpz_and (x, s1, m);
219      MPZ_CHECK_FORMAT (x);
220      if (mpz_cmp (x, s2) != 0)
221        abort ();
222    }
223
224  mpz_clear (x);
225  mpz_clear (s0);
226  mpz_clear (s1);
227  mpz_clear (s2);
228  mpz_clear (s3);
229  mpz_clear (m);
230  return;
231
232
233 fail:
234  printf ("%s\n", s);
235  printf ("bitindex = %lu\n", bitindex);
236  printf ("x = "); mpz_out_str (stdout, -16, x); printf (" hex\n");
237  exit (1);
238}
239
240
241
242int
243main (int argc, char *argv[])
244{
245  tests_start ();
246
247  check_tstbit ();
248  check_random (argc, argv);
249  check_single ();
250
251  tests_end ();
252  exit (0);
253}
254
255
Note: See TracBrowser for help on using the repository browser.