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

     1  /* Test that routines allow reusing a source variable as destination.
     2  
     3  Copyright 1996, 2000-2002, 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  #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, mpf_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 mpf_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  #ifndef EXPO
    50  #define EXPO 32
    51  #endif
    52  
    53  void dump_abort (const char *, mpf_t, mpf_t);
    54  
    55  typedef void (*dss_func) (mpf_ptr, mpf_srcptr, mpf_srcptr);
    56  
    57  dss_func dss_funcs[] =
    58  {
    59    mpf_div, mpf_add, mpf_mul, mpf_sub,
    60  };
    61  
    62  const char *dss_func_names[] =
    63  {
    64    "mpf_div", "mpf_add", "mpf_mul", "mpf_sub",
    65  };
    66  
    67  typedef void (*dsi_func) (mpf_ptr, mpf_srcptr, unsigned long int);
    68  
    69  dsi_func dsi_funcs[] =
    70  {
    71    mpf_div_ui, mpf_add_ui, mpf_mul_ui, mpf_sub_ui,
    72    mpf_mul_2exp, mpf_div_2exp, mpf_pow_ui
    73  };
    74  
    75  const char *dsi_func_names[] =
    76  {
    77    "mpf_div_ui", "mpf_add_ui", "mpf_mul_ui", "mpf_sub_ui",
    78    "mpf_mul_2exp", "mpf_div_2exp", "mpf_pow_ui"
    79  };
    80  
    81  typedef void (*dis_func) (mpf_ptr, unsigned long int, mpf_srcptr);
    82  
    83  dis_func dis_funcs[] =
    84  {
    85    mpf_ui_div, mpf_ui_sub,
    86  };
    87  
    88  const char *dis_func_names[] =
    89  {
    90    "mpf_ui_div", "mpf_ui_sub",
    91  };
    92  
    93  int
    94  main (int argc, char **argv)
    95  {
    96    int i;
    97    int pass, reps = 10000;
    98    mpf_t in1, in2, out1;
    99    unsigned long int in1i, in2i;
   100    mpf_t res1, res2, res3;
   101    mp_size_t bprec = 100;
   102  
   103    tests_start ();
   104  
   105    if (argc > 1)
   106      {
   107        reps = strtol (argv[1], 0, 0);
   108        if (argc > 2)
   109  	bprec = strtol (argv[2], 0, 0);
   110      }
   111  
   112    mpf_set_default_prec (bprec);
   113  
   114    mpf_init (in1);
   115    mpf_init (in2);
   116    mpf_init (out1);
   117    mpf_init (res1);
   118    mpf_init (res2);
   119    mpf_init (res3);
   120  
   121    for (pass = 1; pass <= reps; pass++)
   122      {
   123        mpf_random2 (in1, urandom () % SIZE - SIZE/2, urandom () % EXPO);
   124        mpf_random2 (in2, urandom () % SIZE - SIZE/2, urandom () % EXPO);
   125  
   126        for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
   127  	{
   128  	  /* Don't divide by 0.  */
   129  	  if (i == 0 && mpf_cmp_ui (in2, 0) == 0)
   130  	    continue;
   131  
   132  	  (dss_funcs[i]) (res1, in1, in2);
   133  
   134  	  mpf_set (out1, in1);
   135  	  (dss_funcs[i]) (out1, out1, in2);
   136  	  mpf_set (res2, out1);
   137  
   138  	  mpf_set (out1, in2);
   139  	  (dss_funcs[i]) (out1, in1, out1);
   140  	  mpf_set (res3, out1);
   141  
   142  	  if (mpf_cmp (res1, res2) != 0)
   143  	    dump_abort (dss_func_names[i], res1, res2);
   144  	  if (mpf_cmp (res1, res3) != 0)
   145  	    dump_abort (dss_func_names[i], res1, res3);
   146  	}
   147  
   148        in2i = urandom ();
   149        for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
   150  	{
   151  	  unsigned long this_in2i = in2i;
   152  
   153  	  /* Don't divide by 0.  */
   154  	  if (dsi_funcs[i] == mpf_div_ui && this_in2i == 0)
   155  	    continue;
   156  
   157  	  /* Avoid overflow/underflow in the exponent.  */
   158  	  if (dsi_funcs[i] == mpf_mul_2exp || dsi_funcs[i] == mpf_div_2exp)
   159  	    this_in2i %= 0x100000;
   160  	  else if (dsi_funcs[i] == mpf_pow_ui)
   161  	    this_in2i %= 0x1000;
   162  
   163  	  (dsi_funcs[i]) (res1, in1, this_in2i);
   164  
   165  	  mpf_set (out1, in1);
   166  	  (dsi_funcs[i]) (out1, out1, this_in2i);
   167  	  mpf_set (res2, out1);
   168  
   169  	  if (mpf_cmp (res1, res2) != 0)
   170  	    dump_abort (dsi_func_names[i], res1, res2);
   171  	}
   172  
   173        in1i = urandom ();
   174        for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++)
   175  	{
   176  	  /* Don't divide by 0.  */
   177  	  if (dis_funcs[i] == mpf_ui_div
   178  	      && mpf_cmp_ui (in2, 0) == 0)
   179  	    continue;
   180  
   181  	  (dis_funcs[i]) (res1, in1i, in2);
   182  
   183  	  mpf_set (out1, in2);
   184  	  (dis_funcs[i]) (out1, in1i, out1);
   185  	  mpf_set (res2, out1);
   186  
   187  	  if (mpf_cmp (res1, res2) != 0)
   188  	    dump_abort (dis_func_names[i], res1, res2);
   189  	}
   190  
   191      }
   192  
   193    mpf_clear (in1);
   194    mpf_clear (in2);
   195    mpf_clear (out1);
   196    mpf_clear (res1);
   197    mpf_clear (res2);
   198    mpf_clear (res3);
   199  
   200    tests_end ();
   201    exit (0);
   202  }
   203  
   204  void
   205  dump_abort (const char *name, mpf_t res1, mpf_t res2)
   206  {
   207    printf ("failure in %s:\n", name);
   208    mpf_dump (res1);
   209    mpf_dump (res2);
   210    abort ();
   211  }
   212  
   213  #if 0
   214  void mpf_abs		(mpf_ptr, mpf_srcptr);
   215  void mpf_sqrt		(mpf_ptr, mpf_srcptr);
   216  void mpf_neg		(mpf_ptr, mpf_srcptr);
   217  #endif
   218  
   219  #endif /* ! DLL_EXPORT */