Home | History | Annotate | Line # | Download | only in mpz
t-bit.c revision 1.1
      1  1.1  mrg /* Test mpz_setbit, mpz_clrbit, mpz_tstbit.
      2  1.1  mrg 
      3  1.1  mrg Copyright 1997, 2000-2003, 2012, 2013 Free Software Foundation, Inc.
      4  1.1  mrg 
      5  1.1  mrg This file is part of the GNU MP Library test suite.
      6  1.1  mrg 
      7  1.1  mrg The GNU MP Library test suite is free software; you can redistribute it
      8  1.1  mrg and/or modify it under the terms of the GNU General Public License as
      9  1.1  mrg published by the Free Software Foundation; either version 3 of the License,
     10  1.1  mrg or (at your option) any later version.
     11  1.1  mrg 
     12  1.1  mrg The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1  mrg Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License along with
     18  1.1  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19  1.1  mrg 
     20  1.1  mrg #include <stdio.h>
     21  1.1  mrg #include <stdlib.h>
     22  1.1  mrg 
     23  1.1  mrg #include "gmp-impl.h"
     24  1.1  mrg #include "tests.h"
     25  1.1  mrg 
     26  1.1  mrg #ifndef SIZE
     27  1.1  mrg #define SIZE 4
     28  1.1  mrg #endif
     29  1.1  mrg 
     30  1.1  mrg 
     31  1.1  mrg void
     32  1.1  mrg debug_mp (mpz_srcptr x, int base)
     33  1.1  mrg {
     34  1.1  mrg   mpz_out_str (stdout, base, x); fputc ('\n', stdout);
     35  1.1  mrg }
     36  1.1  mrg 
     37  1.1  mrg 
     38  1.1  mrg /* exercise the case where mpz_clrbit or mpz_combit ends up extending a
     39  1.1  mrg    value like -2^(k*GMP_NUMB_BITS-1) when clearing bit k*GMP_NUMB_BITS-1.  */
     40  1.1  mrg /* And vice-versa. */
     41  1.1  mrg void
     42  1.1  mrg check_clr_extend (void)
     43  1.1  mrg {
     44  1.1  mrg   mpz_t          got, want;
     45  1.1  mrg   unsigned long  i;
     46  1.1  mrg   int            f;
     47  1.1  mrg 
     48  1.1  mrg   mpz_init (got);
     49  1.1  mrg   mpz_init (want);
     50  1.1  mrg 
     51  1.1  mrg   for (i = 1; i < 5; i++)
     52  1.1  mrg     {
     53  1.1  mrg       for (f = 0; f <= 1; f++)
     54  1.1  mrg 	{
     55  1.1  mrg 	  /* lots of 1 bits in _mp_d */
     56  1.1  mrg 	  mpz_set_si (got, 1L);
     57  1.1  mrg 	  mpz_mul_2exp (got, got, 10*GMP_NUMB_BITS);
     58  1.1  mrg 	  mpz_sub_ui (got, got, 1L);
     59  1.1  mrg 
     60  1.1  mrg 	  /* value -2^(n-1) representing ..11100..00 */
     61  1.1  mrg 	  mpz_set_si (got, -1L);
     62  1.1  mrg 	  mpz_mul_2exp (got, got, i*GMP_NUMB_BITS-1);
     63  1.1  mrg 
     64  1.1  mrg 	  /* complement bit n, giving ..11000..00 which is -2^n */
     65  1.1  mrg 	  if (f == 0)
     66  1.1  mrg 	    mpz_clrbit (got, i*GMP_NUMB_BITS-1);
     67  1.1  mrg 	  else
     68  1.1  mrg 	    mpz_combit (got, i*GMP_NUMB_BITS-1);
     69  1.1  mrg 	  MPZ_CHECK_FORMAT (got);
     70  1.1  mrg 
     71  1.1  mrg 	  mpz_set_si (want, -1L);
     72  1.1  mrg 	  mpz_mul_2exp (want, want, i*GMP_NUMB_BITS);
     73  1.1  mrg 
     74  1.1  mrg 	  if (mpz_cmp (got, want) != 0)
     75  1.1  mrg 	    {
     76  1.1  mrg 	      if (f == 0)
     77  1.1  mrg 		printf ("mpz_clrbit: ");
     78  1.1  mrg 	      else
     79  1.1  mrg 		printf ("mpz_combit: ");
     80  1.1  mrg 	      printf ("wrong after extension\n");
     81  1.1  mrg 	      mpz_trace ("got ", got);
     82  1.1  mrg 	      mpz_trace ("want", want);
     83  1.1  mrg 	      abort ();
     84  1.1  mrg 	    }
     85  1.1  mrg 
     86  1.1  mrg 	  /* complement bit n, going back to ..11100..00 which is -2^(n-1) */
     87  1.1  mrg 	  if (f == 0)
     88  1.1  mrg 	    mpz_setbit (got, i*GMP_NUMB_BITS-1);
     89  1.1  mrg 	  else
     90  1.1  mrg 	    mpz_combit (got, i*GMP_NUMB_BITS-1);
     91  1.1  mrg 	  MPZ_CHECK_FORMAT (got);
     92  1.1  mrg 
     93  1.1  mrg 	  mpz_set_si (want, -1L);
     94  1.1  mrg 	  mpz_mul_2exp (want, want, i*GMP_NUMB_BITS - 1);
     95  1.1  mrg 
     96  1.1  mrg 	  if (mpz_cmp (got, want) != 0)
     97  1.1  mrg 	    {
     98  1.1  mrg 	      if (f == 0)
     99  1.1  mrg 		printf ("mpz_setbit: ");
    100  1.1  mrg 	      else
    101  1.1  mrg 		printf ("mpz_combit: ");
    102  1.1  mrg 	      printf ("wrong after shrinking\n");
    103  1.1  mrg 	      mpz_trace ("got ", got);
    104  1.1  mrg 	      mpz_trace ("want", want);
    105  1.1  mrg 	      abort ();
    106  1.1  mrg 	    }
    107  1.1  mrg 	}
    108  1.1  mrg     }
    109  1.1  mrg 
    110  1.1  mrg   mpz_clear (got);
    111  1.1  mrg   mpz_clear (want);
    112  1.1  mrg }
    113  1.1  mrg 
    114  1.1  mrg void
    115  1.1  mrg check_com_negs (void)
    116  1.1  mrg {
    117  1.1  mrg   static const struct {
    118  1.1  mrg     unsigned long  bit;
    119  1.1  mrg     mp_size_t      inp_size;
    120  1.1  mrg     mp_limb_t      inp_n[5];
    121  1.1  mrg     mp_size_t      want_size;
    122  1.1  mrg     mp_limb_t      want_n[5];
    123  1.1  mrg   } data[] = {
    124  1.1  mrg     { GMP_NUMB_BITS,   2, { 1, 1 },  1, { 1 } },
    125  1.1  mrg     { GMP_NUMB_BITS+1, 2, { 1, 1 },  2, { 1, 3 } },
    126  1.1  mrg 
    127  1.1  mrg     { GMP_NUMB_BITS,   2, { 0, 1 },  2, { 0, 2 } },
    128  1.1  mrg     { GMP_NUMB_BITS+1, 2, { 0, 1 },  2, { 0, 3 } },
    129  1.1  mrg   };
    130  1.1  mrg   mpz_t  inp, got, want;
    131  1.1  mrg   int    i;
    132  1.1  mrg 
    133  1.1  mrg   mpz_init (got);
    134  1.1  mrg   mpz_init (want);
    135  1.1  mrg   mpz_init (inp);
    136  1.1  mrg 
    137  1.1  mrg   for (i = 0; i < numberof (data); i++)
    138  1.1  mrg     {
    139  1.1  mrg       mpz_set_n (inp, data[i].inp_n, data[i].inp_size);
    140  1.1  mrg       mpz_neg (inp, inp);
    141  1.1  mrg 
    142  1.1  mrg       mpz_set_n (want, data[i].want_n, data[i].want_size);
    143  1.1  mrg       mpz_neg (want, want);
    144  1.1  mrg 
    145  1.1  mrg       mpz_set (got, inp);
    146  1.1  mrg       mpz_combit (got, data[i].bit);
    147  1.1  mrg 
    148  1.1  mrg       if (mpz_cmp (got, want) != 0)
    149  1.1  mrg 	{
    150  1.1  mrg 	  printf ("mpz_combit: wrong on neg data[%d]\n", i);
    151  1.1  mrg 	  mpz_trace ("inp ", inp);
    152  1.1  mrg 	  printf    ("bit %lu\n", data[i].bit);
    153  1.1  mrg 	  mpz_trace ("got ", got);
    154  1.1  mrg 	  mpz_trace ("want", want);
    155  1.1  mrg 	  abort ();
    156  1.1  mrg 	}
    157  1.1  mrg     }
    158  1.1  mrg 
    159  1.1  mrg   mpz_clear (inp);
    160  1.1  mrg   mpz_clear (got);
    161  1.1  mrg   mpz_clear (want);
    162  1.1  mrg }
    163  1.1  mrg 
    164  1.1  mrg /* See that mpz_tstbit matches a twos complement calculated explicitly, for
    165  1.1  mrg    various low zeros.  */
    166  1.1  mrg void
    167  1.1  mrg check_tstbit (void)
    168  1.1  mrg {
    169  1.1  mrg #define MAX_ZEROS  3
    170  1.1  mrg #define NUM_LIMBS  3
    171  1.1  mrg 
    172  1.1  mrg   mp_limb_t      pos[1+NUM_LIMBS+MAX_ZEROS];
    173  1.1  mrg   mp_limb_t      neg[1+NUM_LIMBS+MAX_ZEROS];
    174  1.1  mrg   mpz_t          z;
    175  1.1  mrg   unsigned long  i;
    176  1.1  mrg   int            zeros, low1;
    177  1.1  mrg   int            got, want;
    178  1.1  mrg 
    179  1.1  mrg   mpz_init (z);
    180  1.1  mrg   for (zeros = 0; zeros <= MAX_ZEROS; zeros++)
    181  1.1  mrg     {
    182  1.1  mrg       MPN_ZERO (pos, numberof(pos));
    183  1.1  mrg       mpn_random2 (pos+zeros, (mp_size_t) NUM_LIMBS);
    184  1.1  mrg 
    185  1.1  mrg       for (low1 = 0; low1 <= 1; low1++)
    186  1.1  mrg 	{
    187  1.1  mrg 	  if (low1)
    188  1.1  mrg 	    pos[0] |= 1;
    189  1.1  mrg 
    190  1.1  mrg 	  refmpn_neg (neg, pos, (mp_size_t) numberof(neg));
    191  1.1  mrg 	  mpz_set_n (z, neg, (mp_size_t) numberof(neg));
    192  1.1  mrg 	  mpz_neg (z, z);
    193  1.1  mrg 
    194  1.1  mrg 	  for (i = 0; i < numberof(pos)*GMP_NUMB_BITS; i++)
    195  1.1  mrg 	    {
    196  1.1  mrg 	      got = mpz_tstbit (z, i);
    197  1.1  mrg 	      want = refmpn_tstbit (pos, i);
    198  1.1  mrg 	      if (got != want)
    199  1.1  mrg 		{
    200  1.1  mrg 		  printf ("wrong at bit %lu, with %d zeros\n", i, zeros);
    201  1.1  mrg 		  printf ("z neg "); debug_mp (z, -16);
    202  1.1  mrg 		  mpz_set_n (z, pos, (mp_size_t) numberof(pos));
    203  1.1  mrg 		  printf ("pos   "); debug_mp (z, -16);
    204  1.1  mrg 		  mpz_set_n (z, neg, (mp_size_t) numberof(neg));
    205  1.1  mrg 		  printf ("neg   "); debug_mp (z, -16);
    206  1.1  mrg 		  exit (1);
    207  1.1  mrg 		}
    208  1.1  mrg 	    }
    209  1.1  mrg 	}
    210  1.1  mrg     }
    211  1.1  mrg   mpz_clear (z);
    212  1.1  mrg }
    213  1.1  mrg 
    214  1.1  mrg 
    215  1.1  mrg void
    216  1.1  mrg check_single (void)
    217  1.1  mrg {
    218  1.1  mrg   mpz_t  x;
    219  1.1  mrg   int    limb, offset, initial;
    220  1.1  mrg   unsigned long  bit;
    221  1.1  mrg 
    222  1.1  mrg   mpz_init (x);
    223  1.1  mrg 
    224  1.1  mrg   for (limb = 0; limb < 4; limb++)
    225  1.1  mrg     {
    226  1.1  mrg       for (offset = (limb==0 ? 0 : -2); offset <= 2; offset++)
    227  1.1  mrg 	{
    228  1.1  mrg 	  for (initial = 1; initial >= -1; initial--)
    229  1.1  mrg 	    {
    230  1.1  mrg 	      mpz_set_si (x, (long) initial);
    231  1.1  mrg 
    232  1.1  mrg 	      bit = (unsigned long) limb*GMP_LIMB_BITS + offset;
    233  1.1  mrg 
    234  1.1  mrg 	      mpz_clrbit (x, bit);
    235  1.1  mrg 	      MPZ_CHECK_FORMAT (x);
    236  1.1  mrg 	      if (mpz_tstbit (x, bit) != 0)
    237  1.1  mrg 		{
    238  1.1  mrg 		  printf ("check_single(): expected 0\n");
    239  1.1  mrg 		  abort ();
    240  1.1  mrg 		}
    241  1.1  mrg 
    242  1.1  mrg 	      mpz_setbit (x, bit);
    243  1.1  mrg 	      MPZ_CHECK_FORMAT (x);
    244  1.1  mrg 	      if (mpz_tstbit (x, bit) != 1)
    245  1.1  mrg 		{
    246  1.1  mrg 		  printf ("check_single(): expected 1\n");
    247  1.1  mrg 		  abort ();
    248  1.1  mrg 		}
    249  1.1  mrg 
    250  1.1  mrg 	      mpz_clrbit (x, bit);
    251  1.1  mrg 	      MPZ_CHECK_FORMAT (x);
    252  1.1  mrg 	      if (mpz_tstbit (x, bit) != 0)
    253  1.1  mrg 		{
    254  1.1  mrg 		  printf ("check_single(): expected 0\n");
    255  1.1  mrg 		  abort ();
    256  1.1  mrg 		}
    257  1.1  mrg 
    258  1.1  mrg 	      mpz_combit (x, bit);
    259  1.1  mrg 	      MPZ_CHECK_FORMAT (x);
    260  1.1  mrg 	      if (mpz_tstbit (x, bit) != 1)
    261  1.1  mrg 		{
    262  1.1  mrg 		  printf ("check_single(): expected 1\n");
    263  1.1  mrg 		  abort ();
    264  1.1  mrg 		}
    265  1.1  mrg 
    266  1.1  mrg 	      mpz_combit (x, bit);
    267  1.1  mrg 	      MPZ_CHECK_FORMAT (x);
    268  1.1  mrg 	      if (mpz_tstbit (x, bit) != 0)
    269  1.1  mrg 		{
    270  1.1  mrg 		  printf ("check_single(): expected 0\n");
    271  1.1  mrg 		  abort ();
    272  1.1  mrg 		}
    273  1.1  mrg 	    }
    274  1.1  mrg 	}
    275  1.1  mrg     }
    276  1.1  mrg 
    277  1.1  mrg   mpz_clear (x);
    278  1.1  mrg }
    279  1.1  mrg 
    280  1.1  mrg 
    281  1.1  mrg void
    282  1.1  mrg check_random (int argc, char *argv[])
    283  1.1  mrg {
    284  1.1  mrg   mpz_t x, s0, s1, s2, s3, m;
    285  1.1  mrg   mp_size_t xsize;
    286  1.1  mrg   int i;
    287  1.1  mrg   int reps = 100000;
    288  1.1  mrg   int bit0, bit1, bit2, bit3;
    289  1.1  mrg   unsigned long int bitindex;
    290  1.1  mrg   const char  *s = "";
    291  1.1  mrg 
    292  1.1  mrg   if (argc == 2)
    293  1.1  mrg     reps = atoi (argv[1]);
    294  1.1  mrg 
    295  1.1  mrg   mpz_init (x);
    296  1.1  mrg   mpz_init (s0);
    297  1.1  mrg   mpz_init (s1);
    298  1.1  mrg   mpz_init (s2);
    299  1.1  mrg   mpz_init (s3);
    300  1.1  mrg   mpz_init (m);
    301  1.1  mrg 
    302  1.1  mrg   for (i = 0; i < reps; i++)
    303  1.1  mrg     {
    304  1.1  mrg       xsize = urandom () % (2 * SIZE) - SIZE;
    305  1.1  mrg       mpz_random2 (x, xsize);
    306  1.1  mrg       bitindex = urandom () % SIZE;
    307  1.1  mrg 
    308  1.1  mrg       mpz_set (s0, x);
    309  1.1  mrg       bit0 = mpz_tstbit (x, bitindex);
    310  1.1  mrg       mpz_setbit (x, bitindex);
    311  1.1  mrg       MPZ_CHECK_FORMAT (x);
    312  1.1  mrg 
    313  1.1  mrg       mpz_set (s1, x);
    314  1.1  mrg       bit1 = mpz_tstbit (x, bitindex);
    315  1.1  mrg       mpz_clrbit (x, bitindex);
    316  1.1  mrg       MPZ_CHECK_FORMAT (x);
    317  1.1  mrg 
    318  1.1  mrg       mpz_set (s2, x);
    319  1.1  mrg       bit2 = mpz_tstbit (x, bitindex);
    320  1.1  mrg       mpz_combit (x, bitindex);
    321  1.1  mrg       MPZ_CHECK_FORMAT (x);
    322  1.1  mrg 
    323  1.1  mrg       mpz_set (s3, x);
    324  1.1  mrg       bit3 = mpz_tstbit (x, bitindex);
    325  1.1  mrg 
    326  1.1  mrg #define FAIL(str) do { s = str; goto fail; } while (0)
    327  1.1  mrg 
    328  1.1  mrg       if (bit1 != 1)  FAIL ("bit1 != 1");
    329  1.1  mrg       if (bit2 != 0)  FAIL ("bit2 != 0");
    330  1.1  mrg       if (bit3 != 1)  FAIL ("bit3 != 1");
    331  1.1  mrg 
    332  1.1  mrg       if (bit0 == 0)
    333  1.1  mrg 	{
    334  1.1  mrg 	  if (mpz_cmp (s0, s1) == 0 || mpz_cmp (s0, s2) != 0 || mpz_cmp (s0, s3) == 0)
    335  1.1  mrg 	    abort ();
    336  1.1  mrg 	}
    337  1.1  mrg       else
    338  1.1  mrg 	{
    339  1.1  mrg 	  if (mpz_cmp (s0, s1) != 0 || mpz_cmp (s0, s2) == 0 || mpz_cmp (s0, s3) != 0)
    340  1.1  mrg 	    abort ();
    341  1.1  mrg 	}
    342  1.1  mrg 
    343  1.1  mrg       if (mpz_cmp (s1, s2) == 0 || mpz_cmp (s1, s3) != 0)
    344  1.1  mrg 	abort ();
    345  1.1  mrg       if (mpz_cmp (s2, s3) == 0)
    346  1.1  mrg 	abort ();
    347  1.1  mrg 
    348  1.1  mrg       mpz_combit (x, bitindex);
    349  1.1  mrg       MPZ_CHECK_FORMAT (x);
    350  1.1  mrg       if (mpz_cmp (s2, x) != 0)
    351  1.1  mrg 	abort ();
    352  1.1  mrg 
    353  1.1  mrg       mpz_clrbit (x, bitindex);
    354  1.1  mrg       MPZ_CHECK_FORMAT (x);
    355  1.1  mrg       if (mpz_cmp (s2, x) != 0)
    356  1.1  mrg 	abort ();
    357  1.1  mrg 
    358  1.1  mrg       mpz_ui_pow_ui (m, 2L, bitindex);
    359  1.1  mrg       MPZ_CHECK_FORMAT (m);
    360  1.1  mrg       mpz_ior (x, s0, m);
    361  1.1  mrg       MPZ_CHECK_FORMAT (x);
    362  1.1  mrg       if (mpz_cmp (x, s3) != 0)
    363  1.1  mrg 	abort ();
    364  1.1  mrg 
    365  1.1  mrg       mpz_com (m, m);
    366  1.1  mrg       MPZ_CHECK_FORMAT (m);
    367  1.1  mrg       mpz_and (x, s0, m);
    368  1.1  mrg       MPZ_CHECK_FORMAT (x);
    369  1.1  mrg       if (mpz_cmp (x, s2) != 0)
    370  1.1  mrg 	abort ();
    371  1.1  mrg     }
    372  1.1  mrg 
    373  1.1  mrg   mpz_clear (x);
    374  1.1  mrg   mpz_clear (s0);
    375  1.1  mrg   mpz_clear (s1);
    376  1.1  mrg   mpz_clear (s2);
    377  1.1  mrg   mpz_clear (s3);
    378  1.1  mrg   mpz_clear (m);
    379  1.1  mrg   return;
    380  1.1  mrg 
    381  1.1  mrg 
    382  1.1  mrg  fail:
    383  1.1  mrg   printf ("%s\n", s);
    384  1.1  mrg   printf ("bitindex = %lu\n", bitindex);
    385  1.1  mrg   printf ("x = "); mpz_out_str (stdout, -16, x); printf (" hex\n");
    386  1.1  mrg   exit (1);
    387  1.1  mrg }
    388  1.1  mrg 
    389  1.1  mrg 
    390  1.1  mrg 
    391  1.1  mrg int
    392  1.1  mrg main (int argc, char *argv[])
    393  1.1  mrg {
    394  1.1  mrg   tests_start ();
    395  1.1  mrg   mp_trace_base = -16;
    396  1.1  mrg 
    397  1.1  mrg   check_clr_extend ();
    398  1.1  mrg   check_com_negs ();
    399  1.1  mrg   check_tstbit ();
    400  1.1  mrg   check_random (argc, argv);
    401  1.1  mrg   check_single ();
    402  1.1  mrg 
    403  1.1  mrg   tests_end ();
    404  1.1  mrg   exit (0);
    405  1.1  mrg }
    406