Home | History | Annotate | Line # | Download | only in tests
      1 /* test mpz_congruent_p
      2 
      3 Copyright 2001, 2002, 2012, 2014 Free Software Foundation, Inc.
      4 
      5 This file is part of the GNU MP Library test suite.
      6 
      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.
     11 
     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.
     16 
     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/.  */
     19 
     20 #include "testutils.h"
     21 
     22 #define MPZ_SRCPTR_SWAP(x, y)						\
     23   do {									\
     24     mpz_srcptr __mpz_srcptr_swap__tmp = (x);				\
     25     (x) = (y);								\
     26     (y) = __mpz_srcptr_swap__tmp;					\
     27   } while (0)
     28 
     29 void
     30 check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
     31 {
     32   int   got;
     33   int   swap;
     34 
     35   for (swap = 0; swap <= 1; swap++)
     36     {
     37       got = (mpz_congruent_p (a, c, d) != 0);
     38       if (want != got)
     39 	{
     40 	  printf ("mpz_congruent_p wrong\n");
     41 	  printf ("   expected %d got %d\n", want, got);
     42 	  dump ("	 a", a);
     43 	  dump ("	 c", c);
     44 	  dump ("	 d", d);
     45 	  abort ();
     46 	}
     47 
     48 #if 0
     49       if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
     50 	{
     51 	  unsigned long	 uc = mpz_get_ui (c);
     52 	  unsigned long	 ud = mpz_get_ui (d);
     53 	  got = (mpz_congruent_ui_p (a, uc, ud) != 0);
     54 	  if (want != got)
     55 	    {
     56 	      printf	("mpz_congruent_ui_p wrong\n");
     57 	      printf	("   expected %d got %d\n", want, got);
     58 	      dump ("   a", a);
     59 	      printf	("   c=%lu\n", uc);
     60 	      printf	("   d=%lu\n", ud);
     61 	      abort ();
     62 	    }
     63 	}
     64 #endif
     65       MPZ_SRCPTR_SWAP (a, c);
     66     }
     67 }
     68 
     69 
     70 void
     71 check_data (void)
     72 {
     73   static const struct {
     74     const char *a;
     75     const char *c;
     76     const char *d;
     77     int        want;
     78 
     79   } data[] = {
     80 
     81     /* strict equality mod 0 */
     82     { "0", "0", "0", 1 },
     83     { "11", "11", "0", 1 },
     84     { "3", "11", "0", 0 },
     85 
     86     /* anything congruent mod 1 */
     87     { "0", "0", "1", 1 },
     88     { "1", "0", "1", 1 },
     89     { "0", "1", "1", 1 },
     90     { "123", "456", "1", 1 },
     91     { "0x123456789123456789", "0x987654321987654321", "1", 1 },
     92 
     93     /* csize==1, dsize==2 changing to 1 after stripping 2s */
     94     { "0x3333333333333333",  "0x33333333",
     95       "0x180000000", 1 },
     96     { "0x33333333333333333333333333333333", "0x3333333333333333",
     97       "0x18000000000000000", 1 },
     98 
     99     /* another dsize==2 becoming 1, with opposite signs this time */
    100     {  "0x444444441",
    101       "-0x22222221F",
    102        "0x333333330", 1 },
    103     {  "0x44444444444444441",
    104       "-0x2222222222222221F",
    105        "0x33333333333333330", 1 },
    106   };
    107 
    108   mpz_t   a, c, d;
    109   unsigned   i;
    110 
    111   mpz_init (a);
    112   mpz_init (c);
    113   mpz_init (d);
    114 
    115   for (i = 0; i < numberof (data); i++)
    116     {
    117       mpz_set_str_or_abort (a, data[i].a, 0);
    118       mpz_set_str_or_abort (c, data[i].c, 0);
    119       mpz_set_str_or_abort (d, data[i].d, 0);
    120       check_one (a, c, d, data[i].want);
    121     }
    122 
    123   mpz_clear (a);
    124   mpz_clear (c);
    125   mpz_clear (d);
    126 }
    127 
    128 
    129 void
    130 check_random (int argc, char *argv[])
    131 {
    132   mpz_t   a, c, d, ra, rc;
    133   int     i;
    134   int     want;
    135   int     reps = 10000;
    136   mpz_t bs;
    137   unsigned long size_range, size;
    138 
    139   if (argc >= 2)
    140     reps = atoi (argv[1]);
    141 
    142   mpz_init (bs);
    143 
    144   mpz_init (a);
    145   mpz_init (c);
    146   mpz_init (d);
    147   mpz_init (ra);
    148   mpz_init (rc);
    149 
    150   for (i = 0; i < reps; i++)
    151     {
    152       mini_urandomb (bs, 32);
    153       size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
    154 
    155       mini_urandomb (bs, size_range);
    156       size = mpz_get_ui (bs);
    157       mini_rrandomb (a, size);
    158 
    159       mini_urandomb (bs, 32);
    160       size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
    161 
    162       mini_urandomb (bs, size_range);
    163       size = mpz_get_ui (bs);
    164       mini_rrandomb (c, size);
    165 
    166       do
    167 	{
    168 	  mini_urandomb (bs, 32);
    169 	  size_range = mpz_get_ui (bs) % 13 + 1; /* 0..8192 bit operands */
    170 
    171 	  mini_urandomb (bs, size_range);
    172 	  size = mpz_get_ui (bs);
    173 	  mini_rrandomb (d, size);
    174 	}
    175       while (mpz_sgn(d) == 0);
    176 
    177       mini_urandomb (bs, 3);
    178       if (mpz_tstbit (bs, 0))
    179 	mpz_neg (a, a);
    180       if (mpz_tstbit (bs, 1))
    181 	mpz_neg (c, c);
    182       if (mpz_tstbit (bs, 2))
    183 	mpz_neg (d, d);
    184 
    185       mpz_fdiv_r (ra, a, d);
    186       mpz_fdiv_r (rc, c, d);
    187 
    188       want = (mpz_cmp (ra, rc) == 0);
    189       check_one (a, c, d, want);
    190 
    191       mpz_sub (ra, ra, rc);
    192       mpz_sub (a, a, ra);
    193       check_one (a, c, d, 1);
    194 
    195     }
    196 
    197   mpz_clear (bs);
    198 
    199   mpz_clear (a);
    200   mpz_clear (c);
    201   mpz_clear (d);
    202   mpz_clear (ra);
    203   mpz_clear (rc);
    204 }
    205 
    206 
    207 void
    208 testmain (int argc, char *argv[])
    209 {
    210   check_data ();
    211   check_random (argc, argv);
    212 }
    213