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

     1  /* Test mpf_eq.
     2  
     3  Copyright 2009, 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  
    23  #include "gmp.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  #define SZ (2 * sizeof(mp_limb_t))
    28  
    29  void insert_random_low_zero_limbs (mpf_t, gmp_randstate_ptr);
    30  void dump_abort (mpf_t, mpf_t, int, int, int, int, int, long);
    31  void hexdump (mpf_t);
    32  
    33  void
    34  check_data (void)
    35  {
    36    static const struct
    37    {
    38      struct {
    39        int        exp, size;
    40        mp_limb_t  d[10];
    41      } x, y;
    42      mp_bitcnt_t bits;
    43      int want;
    44  
    45    } data[] = {
    46      { { 0, 0, { 0 } },             { 0, 0, { 0 } },    0, 1 },
    47  
    48      { { 0, 1, { 7 } },             { 0, 1, { 7 } },    0, 1 },
    49      { { 0, 1, { 7 } },             { 0, 1, { 7 } },   17, 1 },
    50      { { 0, 1, { 7 } },             { 0, 1, { 7 } }, 4711, 1 },
    51  
    52      { { 0, 1, { 7 } },             { 0, 1, { 6 } },    0, 1 },
    53      { { 0, 1, { 7 } },             { 0, 1, { 6 } },    2, 1 },
    54      { { 0, 1, { 7 } },             { 0, 1, { 6 } },    3, 0 },
    55  
    56      { { 0, 0, { 0 } },             { 0, 1, { 1 } },    0, 0 },
    57      { { 0, 1, { 1 } },             { 0,-1 ,{ 1 } },    0, 0 },
    58      { { 1, 1, { 1 } },             { 0, 1, { 1 } },    0, 0 },
    59  
    60      { { 0, 1, { 8 } },             { 0, 1, { 4 } },    0, 0 },
    61  
    62      { { 0, 2, { 0, 3 } },          { 0, 1, { 3 } }, 1000, 1 },
    63    };
    64  
    65    mpf_t  x, y;
    66    int got, got_swapped;
    67    int i;
    68    mp_trace_base = 16;
    69  
    70    for (i = 0; i < numberof (data); i++)
    71      {
    72        PTR(x) = (mp_ptr) data[i].x.d;
    73        SIZ(x) = data[i].x.size;
    74        EXP(x) = data[i].x.exp;
    75        PREC(x) = numberof (data[i].x.d);
    76        MPF_CHECK_FORMAT (x);
    77  
    78        PTR(y) = (mp_ptr) data[i].y.d;
    79        SIZ(y) = data[i].y.size;
    80        EXP(y) = data[i].y.exp;
    81        PREC(y) = numberof (data[i].y.d);
    82        MPF_CHECK_FORMAT (y);
    83  
    84        got         = mpf_eq (x, y, data[i].bits);
    85        got_swapped = mpf_eq (y, x, data[i].bits);
    86  
    87        if (got != got_swapped || got != data[i].want)
    88  	{
    89  	  printf ("check_data() wrong result at data[%d]\n", i);
    90  	  mpf_trace ("x   ", x);
    91  	  mpf_trace ("y   ", y);
    92  	  printf ("got         %d\n", got);
    93  	  printf ("got_swapped %d\n", got_swapped);
    94  	  printf ("want        %d\n", data[i].want);
    95  	  abort ();
    96          }
    97      }
    98  }
    99  
   100  void
   101  check_random (long reps)
   102  {
   103    unsigned long test;
   104    gmp_randstate_ptr rands = RANDS;
   105    mpf_t a, b, x;
   106    mpz_t ds;
   107    int hibits, lshift1, lshift2;
   108    int xtra;
   109  
   110  #define HIBITS 10
   111  #define LSHIFT1 10
   112  #define LSHIFT2 10
   113  
   114    mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2));
   115  
   116    mpz_init (ds);
   117    mpf_inits (a, b, x, NULL);
   118  
   119    for (test = 0; test < reps; test++)
   120      {
   121        mpz_urandomb (ds, rands, HIBITS);
   122        hibits = mpz_get_ui (ds) + 1;
   123        mpz_urandomb (ds, rands, hibits);
   124        mpz_setbit (ds, hibits  - 1);	/* make sure msb is set */
   125        mpf_set_z (a, ds);
   126        mpf_set_z (b, ds);
   127  
   128        mpz_urandomb (ds, rands, LSHIFT1);
   129        lshift1 = mpz_get_ui (ds);
   130        mpf_mul_2exp (a, a, lshift1 + 1);
   131        mpf_mul_2exp (b, b, lshift1 + 1);
   132        mpf_add_ui (a, a, 1);	/* make a one-bit difference */
   133  
   134        mpz_urandomb (ds, rands, LSHIFT2);
   135        lshift2 = mpz_get_ui (ds);
   136        mpf_mul_2exp (a, a, lshift2);
   137        mpf_mul_2exp (b, b, lshift2);
   138        mpz_urandomb (ds, rands, lshift2);
   139        mpf_set_z (x, ds);
   140        mpf_add (a, a, x);
   141        mpf_add (b, b, x);
   142  
   143        insert_random_low_zero_limbs (a, rands);
   144        insert_random_low_zero_limbs (b, rands);
   145  
   146        if (mpf_eq (a, b, lshift1 + hibits) == 0 ||
   147  	  mpf_eq (b, a, lshift1 + hibits) == 0)
   148  	{
   149  	  dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test);
   150  	}
   151        for (xtra = 1; xtra < 100; xtra++)
   152  	if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 ||
   153  	    mpf_eq (b, a, lshift1 + hibits + xtra) != 0)
   154  	  {
   155  	    dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test);
   156  	  }
   157      }
   158  
   159    mpf_clears (a, b, x, NULL);
   160    mpz_clear (ds);
   161  }
   162  
   163  void
   164  insert_random_low_zero_limbs (mpf_t x, gmp_randstate_ptr rands)
   165  {
   166    mp_size_t max = PREC(x) - SIZ(x);
   167    mp_size_t s;
   168    mpz_t ds; mpz_init (ds);
   169    mpz_urandomb (ds, rands, 32);
   170    s = mpz_get_ui (ds) % (max + 1);
   171    MPN_COPY_DECR (PTR(x) + s, PTR(x), SIZ(x));
   172    MPN_ZERO (PTR(x), s);
   173    SIZ(x) += s;
   174    mpz_clear (ds);
   175  }
   176  
   177  void
   178  dump_abort (mpf_t a, mpf_t b, int cmp_prec, int lshift1, int lshift2, int hibits, int want, long test)
   179  {
   180    printf ("ERROR in test %ld\n", test);
   181    printf ("want %d got %d from mpf_eq\n", want, 1-want);
   182    printf ("cmp_prec = %d\n", cmp_prec);
   183    printf ("lshift1 = %d\n", lshift1);
   184    printf ("lshift2 = %d\n", lshift2);
   185    printf ("hibits = %d\n", hibits);
   186    hexdump (a); puts ("");
   187    hexdump (b); puts ("");
   188    abort ();
   189  }
   190  
   191  void
   192  hexdump (mpf_t x)
   193  {
   194    mp_size_t i;
   195    for (i = ABSIZ(x) - 1; i >= 0; i--)
   196      {
   197        gmp_printf ("%0*MX", SZ, PTR(x)[i]);
   198        if (i != 0)
   199  	printf (" ");
   200      }
   201  }
   202  
   203  int
   204  main (int argc, char *argv[])
   205  {
   206    long reps = 10000;
   207  
   208    if (argc == 2)
   209      reps = strtol (argv[1], 0, 0);
   210  
   211    tests_start ();
   212  
   213    check_data ();
   214    check_random (reps);
   215  
   216    tests_end ();
   217    exit (0);
   218  }