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