1 /* Test mpz_setbit, mpz_clrbit, mpz_tstbit.
3 Copyright 1997, 2000-2003, 2012, 2013 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library test suite.
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
33 debug_mp (mpz_srcptr x, int base)
35 mpz_out_str (stdout, base, x); fputc ('\n', stdout);
39 /* exercise the case where mpz_clrbit or mpz_combit ends up extending a
40 value like -2^(k*GMP_NUMB_BITS-1) when clearing bit k*GMP_NUMB_BITS-1. */
43 check_clr_extend (void)
52 for (i = 1; i < 5; i++)
54 for (f = 0; f <= 1; f++)
56 /* lots of 1 bits in _mp_d */
58 mpz_mul_2exp (got, got, 10*GMP_NUMB_BITS);
59 mpz_sub_ui (got, got, 1L);
61 /* value -2^(n-1) representing ..11100..00 */
62 mpz_set_si (got, -1L);
63 mpz_mul_2exp (got, got, i*GMP_NUMB_BITS-1);
65 /* complement bit n, giving ..11000..00 which is -2^n */
67 mpz_clrbit (got, i*GMP_NUMB_BITS-1);
69 mpz_combit (got, i*GMP_NUMB_BITS-1);
70 MPZ_CHECK_FORMAT (got);
72 mpz_set_si (want, -1L);
73 mpz_mul_2exp (want, want, i*GMP_NUMB_BITS);
75 if (mpz_cmp (got, want) != 0)
78 printf ("mpz_clrbit: ");
80 printf ("mpz_combit: ");
81 printf ("wrong after extension\n");
82 mpz_trace ("got ", got);
83 mpz_trace ("want", want);
87 /* complement bit n, going back to ..11100..00 which is -2^(n-1) */
89 mpz_setbit (got, i*GMP_NUMB_BITS-1);
91 mpz_combit (got, i*GMP_NUMB_BITS-1);
92 MPZ_CHECK_FORMAT (got);
94 mpz_set_si (want, -1L);
95 mpz_mul_2exp (want, want, i*GMP_NUMB_BITS - 1);
97 if (mpz_cmp (got, want) != 0)
100 printf ("mpz_setbit: ");
102 printf ("mpz_combit: ");
103 printf ("wrong after shrinking\n");
104 mpz_trace ("got ", got);
105 mpz_trace ("want", want);
116 check_com_negs (void)
118 static const struct {
125 { GMP_NUMB_BITS, 2, { 1, 1 }, 1, { 1 } },
126 { GMP_NUMB_BITS+1, 2, { 1, 1 }, 2, { 1, 3 } },
128 { GMP_NUMB_BITS, 2, { 0, 1 }, 2, { 0, 2 } },
129 { GMP_NUMB_BITS+1, 2, { 0, 1 }, 2, { 0, 3 } },
131 mpz_t inp, got, want;
138 for (i = 0; i < numberof (data); i++)
140 mpz_set_n (inp, data[i].inp_n, data[i].inp_size);
143 mpz_set_n (want, data[i].want_n, data[i].want_size);
144 mpz_neg (want, want);
147 mpz_combit (got, data[i].bit);
149 if (mpz_cmp (got, want) != 0)
151 printf ("mpz_combit: wrong on neg data[%d]\n", i);
152 mpz_trace ("inp ", inp);
153 printf ("bit %lu\n", data[i].bit);
154 mpz_trace ("got ", got);
155 mpz_trace ("want", want);
165 /* See that mpz_tstbit matches a twos complement calculated explicitly, for
166 various low zeros. */
173 mp_limb_t pos[1+NUM_LIMBS+MAX_ZEROS];
174 mp_limb_t neg[1+NUM_LIMBS+MAX_ZEROS];
181 for (zeros = 0; zeros <= MAX_ZEROS; zeros++)
183 MPN_ZERO (pos, numberof(pos));
184 mpn_random2 (pos+zeros, (mp_size_t) NUM_LIMBS);
186 for (low1 = 0; low1 <= 1; low1++)
191 refmpn_neg (neg, pos, (mp_size_t) numberof(neg));
192 mpz_set_n (z, neg, (mp_size_t) numberof(neg));
195 for (i = 0; i < numberof(pos)*GMP_NUMB_BITS; i++)
197 got = mpz_tstbit (z, i);
198 want = refmpn_tstbit (pos, i);
201 printf ("wrong at bit %lu, with %d zeros\n", i, zeros);
202 printf ("z neg "); debug_mp (z, -16);
203 mpz_set_n (z, pos, (mp_size_t) numberof(pos));
204 printf ("pos "); debug_mp (z, -16);
205 mpz_set_n (z, neg, (mp_size_t) numberof(neg));
206 printf ("neg "); debug_mp (z, -16);
220 int limb, offset, initial;
225 for (limb = 0; limb < 4; limb++)
227 for (offset = (limb==0 ? 0 : -2); offset <= 2; offset++)
229 for (initial = 1; initial >= -1; initial--)
231 mpz_set_si (x, (long) initial);
233 bit = (unsigned long) limb*GMP_LIMB_BITS + offset;
236 MPZ_CHECK_FORMAT (x);
237 if (mpz_tstbit (x, bit) != 0)
239 printf ("check_single(): expected 0\n");
244 MPZ_CHECK_FORMAT (x);
245 if (mpz_tstbit (x, bit) != 1)
247 printf ("check_single(): expected 1\n");
252 MPZ_CHECK_FORMAT (x);
253 if (mpz_tstbit (x, bit) != 0)
255 printf ("check_single(): expected 0\n");
260 MPZ_CHECK_FORMAT (x);
261 if (mpz_tstbit (x, bit) != 1)
263 printf ("check_single(): expected 1\n");
268 MPZ_CHECK_FORMAT (x);
269 if (mpz_tstbit (x, bit) != 0)
271 printf ("check_single(): expected 0\n");
283 check_random (int argc, char *argv[])
285 mpz_t x, s0, s1, s2, s3, m;
289 int bit0, bit1, bit2, bit3;
290 unsigned long int bitindex;
294 reps = atoi (argv[1]);
303 for (i = 0; i < reps; i++)
305 xsize = urandom () % (2 * SIZE) - SIZE;
306 mpz_random2 (x, xsize);
307 bitindex = urandom () % SIZE;
310 bit0 = mpz_tstbit (x, bitindex);
311 mpz_setbit (x, bitindex);
312 MPZ_CHECK_FORMAT (x);
315 bit1 = mpz_tstbit (x, bitindex);
316 mpz_clrbit (x, bitindex);
317 MPZ_CHECK_FORMAT (x);
320 bit2 = mpz_tstbit (x, bitindex);
321 mpz_combit (x, bitindex);
322 MPZ_CHECK_FORMAT (x);
325 bit3 = mpz_tstbit (x, bitindex);
327 #define FAIL(str) do { s = str; goto fail; } while (0)
329 if (bit1 != 1) FAIL ("bit1 != 1");
330 if (bit2 != 0) FAIL ("bit2 != 0");
331 if (bit3 != 1) FAIL ("bit3 != 1");
335 if (mpz_cmp (s0, s1) == 0 || mpz_cmp (s0, s2) != 0 || mpz_cmp (s0, s3) == 0)
340 if (mpz_cmp (s0, s1) != 0 || mpz_cmp (s0, s2) == 0 || mpz_cmp (s0, s3) != 0)
344 if (mpz_cmp (s1, s2) == 0 || mpz_cmp (s1, s3) != 0)
346 if (mpz_cmp (s2, s3) == 0)
349 mpz_combit (x, bitindex);
350 MPZ_CHECK_FORMAT (x);
351 if (mpz_cmp (s2, x) != 0)
354 mpz_clrbit (x, bitindex);
355 MPZ_CHECK_FORMAT (x);
356 if (mpz_cmp (s2, x) != 0)
359 mpz_ui_pow_ui (m, 2L, bitindex);
360 MPZ_CHECK_FORMAT (m);
362 MPZ_CHECK_FORMAT (x);
363 if (mpz_cmp (x, s3) != 0)
367 MPZ_CHECK_FORMAT (m);
369 MPZ_CHECK_FORMAT (x);
370 if (mpz_cmp (x, s2) != 0)
385 printf ("bitindex = %lu\n", bitindex);
386 printf ("x = "); mpz_out_str (stdout, -16, x); printf (" hex\n");
393 main (int argc, char *argv[])
401 check_random (argc, argv);