github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-cong.c (about)

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