(root)/
gmp-6.3.0/
mini-gmp/
tests/
t-cong.c
       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  }