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