(root)/
gmp-6.3.0/
tests/
mpz/
t-cong.c
       1  /* test mpz_congruent_p and mpz_congruent_ui_p
       2  
       3  Copyright 2001, 2002, 2012 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 <stdio.h>
      21  #include <stdlib.h>
      22  #include "gmp-impl.h"
      23  #include "tests.h"
      24  
      25  
      26  void
      27  check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
      28  {
      29    int   got;
      30    int   swap;
      31  
      32    for (swap = 0; swap <= 1; swap++)
      33      {
      34        got = (mpz_congruent_p (a, c, d) != 0);
      35        if (want != got)
      36  	{
      37  	  printf ("mpz_congruent_p wrong\n");
      38  	  printf ("   expected %d got %d\n", want, got);
      39  	  mpz_trace ("	 a", a);
      40  	  mpz_trace ("	 c", c);
      41  	  mpz_trace ("	 d", d);
      42  	  mp_trace_base = -16;
      43  	  mpz_trace ("	 a", a);
      44  	  mpz_trace ("	 c", c);
      45  	  mpz_trace ("	 d", d);
      46  	  abort ();
      47  	}
      48  
      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  	      mpz_trace ("   a", a);
      59  	      printf	("   c=%lu\n", uc);
      60  	      printf	("   d=%lu\n", ud);
      61  	      mp_trace_base = -16;
      62  	      mpz_trace ("   a", a);
      63  	      printf	("   c=0x%lX\n", uc);
      64  	      printf	("   d=0x%lX\n", ud);
      65  	      abort ();
      66  	    }
      67  	}
      68  
      69        MPZ_SRCPTR_SWAP (a, c);
      70      }
      71  }
      72  
      73  
      74  void
      75  check_data (void)
      76  {
      77    static const struct {
      78      const char *a;
      79      const char *c;
      80      const char *d;
      81      int        want;
      82  
      83    } data[] = {
      84  
      85      /* strict equality mod 0 */
      86      { "0", "0", "0", 1 },
      87      { "11", "11", "0", 1 },
      88      { "3", "11", "0", 0 },
      89  
      90      /* anything congruent mod 1 */
      91      { "0", "0", "1", 1 },
      92      { "1", "0", "1", 1 },
      93      { "0", "1", "1", 1 },
      94      { "123", "456", "1", 1 },
      95      { "0x123456789123456789", "0x987654321987654321", "1", 1 },
      96  
      97      /* csize==1, dsize==2 changing to 1 after stripping 2s */
      98      { "0x3333333333333333",  "0x33333333",
      99        "0x180000000", 1 },
     100      { "0x33333333333333333333333333333333", "0x3333333333333333",
     101        "0x18000000000000000", 1 },
     102  
     103      /* another dsize==2 becoming 1, with opposite signs this time */
     104      {  "0x444444441",
     105        "-0x22222221F",
     106         "0x333333330", 1 },
     107      {  "0x44444444444444441",
     108        "-0x2222222222222221F",
     109         "0x33333333333333330", 1 },
     110    };
     111  
     112    mpz_t   a, c, d;
     113    int     i;
     114  
     115    mpz_init (a);
     116    mpz_init (c);
     117    mpz_init (d);
     118  
     119    for (i = 0; i < numberof (data); i++)
     120      {
     121        mpz_set_str_or_abort (a, data[i].a, 0);
     122        mpz_set_str_or_abort (c, data[i].c, 0);
     123        mpz_set_str_or_abort (d, data[i].d, 0);
     124        check_one (a, c, d, data[i].want);
     125      }
     126  
     127    mpz_clear (a);
     128    mpz_clear (c);
     129    mpz_clear (d);
     130  }
     131  
     132  
     133  void
     134  check_random (int argc, char *argv[])
     135  {
     136    gmp_randstate_ptr rands = RANDS;
     137    mpz_t   a, c, d, ra, rc;
     138    int     i;
     139    int     want;
     140    int     reps = 10000;
     141    mpz_t bs;
     142    unsigned long size_range, size;
     143  
     144    if (argc >= 2)
     145      reps = atoi (argv[1]);
     146  
     147    mpz_init (bs);
     148  
     149    mpz_init (a);
     150    mpz_init (c);
     151    mpz_init (d);
     152    mpz_init (ra);
     153    mpz_init (rc);
     154  
     155    for (i = 0; i < reps; i++)
     156      {
     157        mpz_urandomb (bs, rands, 32);
     158        size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
     159  
     160        mpz_urandomb (bs, rands, size_range);
     161        size = mpz_get_ui (bs);
     162        mpz_rrandomb (a, rands, size);
     163  
     164        mpz_urandomb (bs, rands, 32);
     165        size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
     166  
     167        mpz_urandomb (bs, rands, size_range);
     168        size = mpz_get_ui (bs);
     169        mpz_rrandomb (c, rands, size);
     170  
     171        do
     172  	{
     173  	  mpz_urandomb (bs, rands, 32);
     174  	  size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */
     175  
     176  	  mpz_urandomb (bs, rands, size_range);
     177  	  size = mpz_get_ui (bs);
     178  	  mpz_rrandomb (d, rands, size);
     179  	}
     180        while (SIZ(d) == 0);
     181  
     182        mpz_negrandom (a, rands);
     183        MPZ_CHECK_FORMAT (a);
     184        mpz_negrandom (c, rands);
     185        MPZ_CHECK_FORMAT (c);
     186        mpz_negrandom (d, rands);
     187  
     188        mpz_fdiv_r (ra, a, d);
     189        mpz_fdiv_r (rc, c, d);
     190  
     191        want = (mpz_cmp (ra, rc) == 0);
     192        check_one (a, c, d, want);
     193  
     194        mpz_sub (ra, ra, rc);
     195        mpz_sub (a, a, ra);
     196        MPZ_CHECK_FORMAT (a);
     197        check_one (a, c, d, 1);
     198  
     199        if (! mpz_pow2abs_p (d))
     200          {
     201  	  refmpz_combit (a, urandom() % (8*GMP_LIMB_BITS));
     202  	  check_one (a, c, d, 0);
     203          }
     204      }
     205  
     206    mpz_clear (bs);
     207  
     208    mpz_clear (a);
     209    mpz_clear (c);
     210    mpz_clear (d);
     211    mpz_clear (ra);
     212    mpz_clear (rc);
     213  }
     214  
     215  
     216  int
     217  main (int argc, char *argv[])
     218  {
     219    tests_start ();
     220  
     221    check_data ();
     222    check_random (argc, argv);
     223  
     224    tests_end ();
     225    exit (0);
     226  }