1 /* Test mpz_setbit, mpz_clrbit, mpz_tstbit.
3 Copyright 1997, 2000, 2001, 2002, 2003, 2012, 2013 Free Software
6 This file is part of the GNU MP Library test suite.
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.
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.
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/. */
34 debug_mp (mpz_srcptr x, int base)
36 mpz_out_str (stdout, base, x); fputc ('\n', stdout);
40 /* exercise the case where mpz_clrbit or mpz_combit ends up extending a
41 value like -2^(k*GMP_NUMB_BITS-1) when clearing bit k*GMP_NUMB_BITS-1. */
44 check_clr_extend (void)
53 for (i = 1; i < 5; i++)
55 for (f = 0; f <= 1; f++)
57 /* lots of 1 bits in _mp_d */
59 mpz_mul_2exp (got, got, 10*GMP_NUMB_BITS);
60 mpz_sub_ui (got, got, 1L);
62 /* value -2^(n-1) representing ..11100..00 */
63 mpz_set_si (got, -1L);
64 mpz_mul_2exp (got, got, i*GMP_NUMB_BITS-1);
66 /* complement bit n, giving ..11000..00 which is -2^n */
68 mpz_clrbit (got, i*GMP_NUMB_BITS-1);
70 mpz_combit (got, i*GMP_NUMB_BITS-1);
71 MPZ_CHECK_FORMAT (got);
73 mpz_set_si (want, -1L);
74 mpz_mul_2exp (want, want, i*GMP_NUMB_BITS);
76 if (mpz_cmp (got, want) != 0)
79 printf ("mpz_clrbit: ");
81 printf ("mpz_combit: ");
82 printf ("wrong after extension\n");
83 mpz_trace ("got ", got);
84 mpz_trace ("want", want);
88 /* complement bit n, going back to ..11100..00 which is -2^(n-1) */
90 mpz_setbit (got, i*GMP_NUMB_BITS-1);
92 mpz_combit (got, i*GMP_NUMB_BITS-1);
93 MPZ_CHECK_FORMAT (got);
95 mpz_set_si (want, -1L);
96 mpz_mul_2exp (want, want, i*GMP_NUMB_BITS - 1);
98 if (mpz_cmp (got, want) != 0)
101 printf ("mpz_setbit: ");
103 printf ("mpz_combit: ");
104 printf ("wrong after shrinking\n");
105 mpz_trace ("got ", got);
106 mpz_trace ("want", want);
117 check_com_negs (void)
119 static const struct {
126 { GMP_NUMB_BITS, 2, { 1, 1 }, 1, { 1 } },
127 { GMP_NUMB_BITS+1, 2, { 1, 1 }, 2, { 1, 3 } },
129 { GMP_NUMB_BITS, 2, { 0, 1 }, 2, { 0, 2 } },
130 { GMP_NUMB_BITS+1, 2, { 0, 1 }, 2, { 0, 3 } },
132 mpz_t inp, got, want;
139 for (i = 0; i < numberof (data); i++)
141 mpz_set_n (inp, data[i].inp_n, data[i].inp_size);
144 mpz_set_n (want, data[i].want_n, data[i].want_size);
145 mpz_neg (want, want);
148 mpz_combit (got, data[i].bit);
150 if (mpz_cmp (got, want) != 0)
152 printf ("mpz_combit: wrong on neg data[%d]\n", i);
153 mpz_trace ("inp ", inp);
154 printf ("bit %lu\n", data[i].bit);
155 mpz_trace ("got ", got);
156 mpz_trace ("want", want);
166 /* See that mpz_tstbit matches a twos complement calculated explicitly, for
167 various low zeros. */
174 mp_limb_t pos[1+NUM_LIMBS+MAX_ZEROS];
175 mp_limb_t neg[1+NUM_LIMBS+MAX_ZEROS];
182 for (zeros = 0; zeros <= MAX_ZEROS; zeros++)
184 MPN_ZERO (pos, numberof(pos));
185 mpn_random2 (pos+zeros, (mp_size_t) NUM_LIMBS);
187 for (low1 = 0; low1 <= 1; low1++)
192 refmpn_neg (neg, pos, (mp_size_t) numberof(neg));
193 mpz_set_n (z, neg, (mp_size_t) numberof(neg));
196 for (i = 0; i < numberof(pos)*GMP_NUMB_BITS; i++)
198 got = mpz_tstbit (z, i);
199 want = refmpn_tstbit (pos, i);
202 printf ("wrong at bit %lu, with %d zeros\n", i, zeros);
203 printf ("z neg "); debug_mp (z, -16);
204 mpz_set_n (z, pos, (mp_size_t) numberof(pos));
205 printf ("pos "); debug_mp (z, -16);
206 mpz_set_n (z, neg, (mp_size_t) numberof(neg));
207 printf ("neg "); debug_mp (z, -16);
221 int limb, offset, initial;
226 for (limb = 0; limb < 4; limb++)
228 for (offset = (limb==0 ? 0 : -2); offset <= 2; offset++)
230 for (initial = 1; initial >= -1; initial--)
232 mpz_set_si (x, (long) initial);
234 bit = (unsigned long) limb*GMP_LIMB_BITS + offset;
237 MPZ_CHECK_FORMAT (x);
238 if (mpz_tstbit (x, bit) != 0)
240 printf ("check_single(): expected 0\n");
245 MPZ_CHECK_FORMAT (x);
246 if (mpz_tstbit (x, bit) != 1)
248 printf ("check_single(): expected 1\n");
253 MPZ_CHECK_FORMAT (x);
254 if (mpz_tstbit (x, bit) != 0)
256 printf ("check_single(): expected 0\n");
261 MPZ_CHECK_FORMAT (x);
262 if (mpz_tstbit (x, bit) != 1)
264 printf ("check_single(): expected 1\n");
269 MPZ_CHECK_FORMAT (x);
270 if (mpz_tstbit (x, bit) != 0)
272 printf ("check_single(): expected 0\n");
284 check_random (int argc, char *argv[])
286 mpz_t x, s0, s1, s2, s3, m;
290 int bit0, bit1, bit2, bit3;
291 unsigned long int bitindex;
295 reps = atoi (argv[1]);
304 for (i = 0; i < reps; i++)
306 xsize = urandom () % (2 * SIZE) - SIZE;
307 mpz_random2 (x, xsize);
308 bitindex = urandom () % SIZE;
311 bit0 = mpz_tstbit (x, bitindex);
312 mpz_setbit (x, bitindex);
313 MPZ_CHECK_FORMAT (x);
316 bit1 = mpz_tstbit (x, bitindex);
317 mpz_clrbit (x, bitindex);
318 MPZ_CHECK_FORMAT (x);
321 bit2 = mpz_tstbit (x, bitindex);
322 mpz_combit (x, bitindex);
323 MPZ_CHECK_FORMAT (x);
326 bit3 = mpz_tstbit (x, bitindex);
328 #define FAIL(str) do { s = str; goto fail; } while (0)
330 if (bit1 != 1) FAIL ("bit1 != 1");
331 if (bit2 != 0) FAIL ("bit2 != 0");
332 if (bit3 != 1) FAIL ("bit3 != 1");
336 if (mpz_cmp (s0, s1) == 0 || mpz_cmp (s0, s2) != 0 || mpz_cmp (s0, s3) == 0)
341 if (mpz_cmp (s0, s1) != 0 || mpz_cmp (s0, s2) == 0 || mpz_cmp (s0, s3) != 0)
345 if (mpz_cmp (s1, s2) == 0 || mpz_cmp (s1, s3) != 0)
347 if (mpz_cmp (s2, s3) == 0)
350 mpz_combit (x, bitindex);
351 MPZ_CHECK_FORMAT (x);
352 if (mpz_cmp (s2, x) != 0)
355 mpz_clrbit (x, bitindex);
356 MPZ_CHECK_FORMAT (x);
357 if (mpz_cmp (s2, x) != 0)
360 mpz_ui_pow_ui (m, 2L, bitindex);
361 MPZ_CHECK_FORMAT (m);
363 MPZ_CHECK_FORMAT (x);
364 if (mpz_cmp (x, s3) != 0)
368 MPZ_CHECK_FORMAT (m);
370 MPZ_CHECK_FORMAT (x);
371 if (mpz_cmp (x, s2) != 0)
386 printf ("bitindex = %lu\n", bitindex);
387 printf ("x = "); mpz_out_str (stdout, -16, x); printf (" hex\n");
394 main (int argc, char *argv[])
402 check_random (argc, argv);