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

     1  /* test mpz_congruent_2exp_p */
     2  
     3  /*
     4  Copyright 2001, 2013 Free Software Foundation, Inc.
     5  
     6  This file is part of the GNU MP Library test suite.
     7  
     8  The GNU MP Library test suite is free software; you can redistribute it
     9  and/or modify it under the terms of the GNU General Public License as
    10  published by the Free Software Foundation; either version 3 of the License,
    11  or (at your option) any later version.
    12  
    13  The GNU MP Library test suite is distributed in the hope that it will be
    14  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    16  Public License for more details.
    17  
    18  You should have received a copy of the GNU General Public License along with
    19  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    20  
    21  #include <stdio.h>
    22  #include <stdlib.h>
    23  #include "gmp.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  
    28  void
    29  check_one (mpz_srcptr a, mpz_srcptr c, unsigned long d, int want)
    30  {
    31    mpz_t  diff, d2exp;
    32    int    got;
    33    int    swap;
    34  
    35    for (swap = 0; swap <= 1; swap++)
    36      {
    37        got = (mpz_congruent_2exp_p (a, c, d) != 0);
    38        if (want != got)
    39          {
    40            mpz_init (diff);
    41            mpz_init (d2exp);
    42  
    43            mpz_sub (diff, a, c);
    44            mpz_set_ui (d2exp, 1L);
    45            mpz_mul_2exp (d2exp, d2exp, d);
    46  
    47            printf ("mpz_congruent_2exp_p wrong\n");
    48            printf ("   expected %d got %d\n", want, got);
    49            mpz_trace ("   a", a);
    50            mpz_trace ("   c", c);
    51            mpz_trace (" a-c", diff);
    52            mpz_trace (" 2^d", d2exp);
    53            printf    ("   d=%lu\n", d);
    54  
    55            mp_trace_base = -16;
    56            mpz_trace ("   a", a);
    57            mpz_trace ("   c", c);
    58            mpz_trace (" a-c", diff);
    59            mpz_trace (" 2^d", d2exp);
    60            printf    ("   d=0x%lX\n", d);
    61            abort ();
    62          }
    63  
    64        MPZ_SRCPTR_SWAP (a, c);
    65      }
    66  }
    67  
    68  
    69  void
    70  check_data (void)
    71  {
    72    static const struct {
    73      const char     *a;
    74      const char     *c;
    75      unsigned long  d;
    76      int            want;
    77  
    78    } data[] = {
    79  
    80      /* anything is congruent mod 1 */
    81      { "0", "0", 0, 1 },
    82      { "1", "0", 0, 1 },
    83      { "0", "1", 0, 1 },
    84      { "123", "-456", 0, 1 },
    85      { "0x123456789123456789", "0x987654321987654321", 0, 1 },
    86      { "0xfffffffffffffffffffffffffffffff7", "-0x9", 129, 0 },
    87      { "0xfffffffffffffffffffffffffffffff6", "-0xa", 128, 1 },
    88  
    89    };
    90  
    91    mpz_t   a, c;
    92    int     i;
    93  
    94    mpz_init (a);
    95    mpz_init (c);
    96  
    97    for (i = 0; i < numberof (data); i++)
    98      {
    99        mpz_set_str_or_abort (a, data[i].a, 0);
   100        mpz_set_str_or_abort (c, data[i].c, 0);
   101        check_one (a, c, data[i].d, data[i].want);
   102      }
   103  
   104    mpz_clear (a);
   105    mpz_clear (c);
   106  }
   107  
   108  
   109  void
   110  check_random (int reps)
   111  {
   112    gmp_randstate_ptr rands = RANDS;
   113    unsigned long  d;
   114    mpz_t  a, c, ra, rc;
   115    int    i;
   116  
   117    mpz_init (a);
   118    mpz_init (c);
   119    mpz_init (ra);
   120    mpz_init (rc);
   121  
   122    for (i = 0; i < reps; i++)
   123      {
   124        mpz_errandomb (a, rands, 8*GMP_LIMB_BITS);
   125        mpz_errandomb (c, rands, 8*GMP_LIMB_BITS);
   126        d = urandom() % (8*GMP_LIMB_BITS);
   127  
   128        mpz_mul_2exp (a, a, urandom() % (2*GMP_LIMB_BITS));
   129        mpz_mul_2exp (c, c, urandom() % (2*GMP_LIMB_BITS));
   130  
   131        mpz_negrandom (a, rands);
   132        mpz_negrandom (c, rands);
   133  
   134        mpz_fdiv_r_2exp (ra, a, d);
   135        mpz_fdiv_r_2exp (rc, c, d);
   136  
   137        mpz_sub (ra, ra, rc);
   138        if (mpz_cmp_ui (ra, 0) != 0)
   139  	{
   140  	  check_one (a, c, d, 0);
   141  	  mpz_sub (a, a, ra);
   142  	}
   143        check_one (a, c, d, 1);
   144        if (d != 0)
   145  	{
   146  	  mpz_combit (a, urandom() % d);
   147  	  check_one (a, c, d, 0);
   148  	}
   149      }
   150  
   151    mpz_clear (a);
   152    mpz_clear (c);
   153    mpz_clear (ra);
   154    mpz_clear (rc);
   155  }
   156  
   157  void
   158  check_random_bits (int reps)
   159  {
   160    mp_bitcnt_t ea, ec, en, d;
   161    mp_bitcnt_t m = 10 * GMP_LIMB_BITS;
   162    mpz_t  a, c;
   163    int    i;
   164  
   165    mpz_init2 (a, m + 1);
   166    mpz_init2 (c, m);
   167  
   168    for (i = 0; i < reps; i++)
   169      {
   170        d  = urandom() % m;
   171        ea = urandom() % m;
   172        ec = urandom() % m;
   173        en = urandom() % m;
   174  
   175        mpz_set_ui (c, 0);
   176        mpz_setbit (c, en);
   177  
   178        mpz_set_ui (a, 0);
   179        mpz_setbit (a, ec);
   180        mpz_sub (c , a, c);
   181  
   182        mpz_set_ui (a, 0);
   183        mpz_setbit (a, ea);
   184        mpz_add (a , a, c);
   185  
   186        check_one (a, c, d, ea >= d);
   187      }
   188  
   189    mpz_clear (a);
   190    mpz_clear (c);
   191  }
   192  
   193  
   194  int
   195  main (int argc, char *argv[])
   196  {
   197    int    reps = 5000;
   198  
   199    tests_start ();
   200    TESTS_REPS (reps, argv, argc);
   201  
   202    check_data ();
   203    check_random (reps);
   204    check_random_bits (reps);
   205  
   206    tests_end ();
   207    exit (0);
   208  }