github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpq/reuse.c (about)

     1  /* Test that routines allow reusing a source variable as destination.
     2  
     3  Copyright 1996, 2000-2002, 2012, 2015 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 <string.h>
    23  
    24  #include "gmp.h"
    25  #include "gmp-impl.h"
    26  #include "tests.h"
    27  
    28  #if __GMP_LIBGMP_DLL
    29  
    30  /* FIXME: When linking to a DLL libgmp, mpq_add etc can't be used as
    31     initializers for global variables because they're effectively global
    32     variables (function pointers) themselves.  Perhaps calling a test
    33     function successively with mpq_add etc would be better.  */
    34  
    35  int
    36  main (void)
    37  {
    38    printf ("Test suppressed for windows DLL\n");
    39    exit (0);
    40  }
    41  
    42  
    43  #else /* ! DLL_EXPORT */
    44  
    45  #ifndef SIZE
    46  #define SIZE 16
    47  #endif
    48  
    49  void dump_abort (const char *, mpq_t, mpq_t);
    50  
    51  typedef void (*dss_func) (mpq_ptr, mpq_srcptr, mpq_srcptr);
    52  
    53  dss_func dss_funcs[] =
    54  {
    55    mpq_div, mpq_add, mpq_mul, mpq_sub,
    56  };
    57  
    58  const char *dss_func_names[] =
    59  {
    60    "mpq_div", "mpq_add", "mpq_mul", "mpq_sub",
    61  };
    62  
    63  typedef void (*ds_func) (mpq_ptr, mpq_srcptr);
    64  
    65  ds_func ds_funcs[] =
    66  {
    67    mpq_abs, mpq_neg,
    68  };
    69  
    70  const char *ds_func_names[] =
    71  {
    72    "mpq_abs", "mpq_neg",
    73  };
    74  
    75  typedef void (*dsi_func) (mpq_ptr, mpq_srcptr, unsigned long int);
    76  
    77  dsi_func dsi_funcs[] =
    78  {
    79    mpq_mul_2exp, mpq_div_2exp
    80  };
    81  
    82  const char *dsi_func_names[] =
    83  {
    84    "mpq_mul_2exp", "mpq_div_2exp"
    85  };
    86  
    87  int
    88  main (int argc, char **argv)
    89  {
    90    int i;
    91    int pass, reps = 100;
    92    mpq_t in1, in2, out1;
    93    unsigned long int randbits, in2i;
    94    mpq_t res1, res2;
    95    gmp_randstate_ptr  rands;
    96  
    97    tests_start ();
    98  
    99    if (argc > 1)
   100      reps = strtol (argv[1], 0, 0);
   101  
   102    rands = RANDS;
   103  
   104    mpq_init (in1);
   105    mpq_init (in2);
   106    mpq_init (out1);
   107    mpq_init (res1);
   108    mpq_init (res2);
   109  
   110    for (pass = 1; pass <= reps; pass++)
   111      {
   112        randbits = urandom ();
   113  
   114        if (randbits & 1)
   115  	{
   116  	  mpq_clear (in1);
   117  	  mpq_init (in1);
   118  	}
   119        randbits >>= 1;
   120        mpz_errandomb (mpq_numref(in1), rands, 512L);
   121        mpz_errandomb_nonzero (mpq_denref(in1), rands, 512L);
   122        if (randbits & 1)
   123  	mpz_neg (mpq_numref(in1),mpq_numref(in1));
   124        randbits >>= 1;
   125        mpq_canonicalize (in1);
   126  
   127        if (randbits & 1)
   128  	{
   129  	  mpq_clear (in2);
   130  	  mpq_init (in2);
   131  	}
   132        randbits >>= 1;
   133        mpz_errandomb (mpq_numref(in2), rands, 512L);
   134        mpz_errandomb_nonzero (mpq_denref(in2), rands, 512L);
   135        if (randbits & 1)
   136  	mpz_neg (mpq_numref(in2),mpq_numref(in2));
   137        randbits >>= 1;
   138        mpq_canonicalize (in2);
   139  
   140        for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
   141  	{
   142  	  /* Don't divide by 0.  */
   143  	  if (i == 0 && mpq_cmp_ui (in2, 0, 1) == 0)
   144  	    continue;
   145  
   146  	  if (randbits & 1)
   147  	    {
   148  	      mpq_clear (res1);
   149  	      mpq_init (res1);
   150  	    }
   151  	  randbits >>= 1;
   152  
   153  	  (dss_funcs[i]) (res1, in1, in2);
   154  	  MPQ_CHECK_FORMAT(res1);
   155  
   156  	  mpq_set (out1, in1);
   157  	  (dss_funcs[i]) (out1, out1, in2);
   158  	  MPQ_CHECK_FORMAT(out1);
   159  
   160  	  if (mpq_cmp (res1, out1) != 0)
   161  	    dump_abort (dss_func_names[i], res1, out1);
   162  
   163  	  mpq_set (out1, in2);
   164  	  (dss_funcs[i]) (out1, in1, out1);
   165  	  MPQ_CHECK_FORMAT(out1);
   166  
   167  	  if (mpq_cmp (res1, out1) != 0)
   168  	    dump_abort (dss_func_names[i], res1, out1);
   169  
   170  	  mpq_set (out1, in2);
   171  	  (dss_funcs[i]) (res1, out1, in2);
   172  	  MPQ_CHECK_FORMAT(res1);
   173  
   174  	  (dss_funcs[i]) (res2, in2, in2);
   175  	  MPQ_CHECK_FORMAT(res2);
   176  
   177  	  (dss_funcs[i]) (out1, out1, out1);
   178  	  MPQ_CHECK_FORMAT(out1);
   179  
   180  	  if (mpq_cmp (res1, res2) != 0)
   181  	    dump_abort (dss_func_names[i], res1, res2);
   182  	  if (mpq_cmp (res1, out1) != 0)
   183  	    dump_abort (dss_func_names[i], res1, out1);
   184  	}
   185  
   186        for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++)
   187  	{
   188  	  if (randbits & 1)
   189  	    {
   190  	      mpq_clear (res1);
   191  	      mpq_init (res1);
   192  	    }
   193  	  randbits >>= 1;
   194  	  (ds_funcs[i]) (res1, in1);
   195  	  MPQ_CHECK_FORMAT(res1);
   196  
   197  	  mpq_set (out1, in1);
   198  	  (ds_funcs[i]) (out1, out1);
   199  	  MPQ_CHECK_FORMAT(out1);
   200  
   201  	  if (mpq_cmp (res1, out1) != 0)
   202  	    dump_abort (ds_func_names[i], res1, out1);
   203  	}
   204  
   205        in2i = urandom () % 65536;
   206        for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
   207  	{
   208  	  if (randbits & 1)
   209  	    {
   210  	      mpq_clear (res1);
   211  	      mpq_init (res1);
   212  	    }
   213  	  randbits >>= 1;
   214  
   215  	  (dsi_funcs[i]) (res1, in1, in2i);
   216  	  MPQ_CHECK_FORMAT(res1);
   217  
   218  	  mpq_set (out1, in1);
   219  	  (dsi_funcs[i]) (out1, out1, in2i);
   220  	  MPQ_CHECK_FORMAT(out1);
   221  
   222  	  if (mpq_cmp (res1, out1) != 0)
   223  	    dump_abort (dsi_func_names[i], res1, out1);
   224  	}
   225  
   226      }
   227  
   228    mpq_clear (in1);
   229    mpq_clear (in2);
   230    mpq_clear (out1);
   231    mpq_clear (res1);
   232    mpq_clear (res2);
   233  
   234    tests_end ();
   235    exit (0);
   236  }
   237  
   238  void
   239  dump_abort (const char *name, mpq_t res1, mpq_t res2)
   240  {
   241    printf ("failure in %s:\n", name);
   242    mpq_trace ("  res1  ", res1);
   243    mpq_trace ("  res2  ", res2);
   244    abort ();
   245  }
   246  
   247  #endif /* ! DLL_EXPORT */