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