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

     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  }