Home | History | Annotate | Line # | Download | only in mpf
      1      1.1  mrg /* Test that routines allow reusing a source variable as destination.
      2      1.1  mrg 
      3  1.1.1.3  mrg Copyright 1996, 2000-2002, 2012 Free Software Foundation, Inc.
      4      1.1  mrg 
      5  1.1.1.2  mrg This file is part of the GNU MP Library test suite.
      6      1.1  mrg 
      7  1.1.1.2  mrg The GNU MP Library test suite is free software; you can redistribute it
      8  1.1.1.2  mrg and/or modify it under the terms of the GNU General Public License as
      9  1.1.1.2  mrg published by the Free Software Foundation; either version 3 of the License,
     10  1.1.1.2  mrg or (at your option) any later version.
     11  1.1.1.2  mrg 
     12  1.1.1.2  mrg The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1.1.2  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1.1.2  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1.1.2  mrg Public License for more details.
     16      1.1  mrg 
     17  1.1.1.2  mrg You should have received a copy of the GNU General Public License along with
     18  1.1.1.3  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19      1.1  mrg 
     20      1.1  mrg #include <stdio.h>
     21      1.1  mrg #include <stdlib.h>
     22      1.1  mrg #include <string.h>
     23      1.1  mrg 
     24      1.1  mrg #include "gmp-impl.h"
     25      1.1  mrg #include "tests.h"
     26      1.1  mrg 
     27      1.1  mrg #if __GMP_LIBGMP_DLL
     28      1.1  mrg 
     29      1.1  mrg /* FIXME: When linking to a DLL libgmp, mpf_add etc can't be used as
     30      1.1  mrg    initializers for global variables because they're effectively global
     31      1.1  mrg    variables (function pointers) themselves.  Perhaps calling a test
     32      1.1  mrg    function successively with mpf_add etc would be better.  */
     33      1.1  mrg 
     34      1.1  mrg int
     35      1.1  mrg main (void)
     36      1.1  mrg {
     37      1.1  mrg   printf ("Test suppressed for windows DLL\n");
     38      1.1  mrg   exit (0);
     39      1.1  mrg }
     40      1.1  mrg 
     41      1.1  mrg 
     42      1.1  mrg #else /* ! DLL_EXPORT */
     43      1.1  mrg 
     44      1.1  mrg #ifndef SIZE
     45      1.1  mrg #define SIZE 16
     46      1.1  mrg #endif
     47      1.1  mrg 
     48      1.1  mrg #ifndef EXPO
     49      1.1  mrg #define EXPO 32
     50      1.1  mrg #endif
     51      1.1  mrg 
     52  1.1.1.2  mrg void dump_abort (const char *, mpf_t, mpf_t);
     53      1.1  mrg 
     54  1.1.1.2  mrg typedef void (*dss_func) (mpf_ptr, mpf_srcptr, mpf_srcptr);
     55      1.1  mrg 
     56      1.1  mrg dss_func dss_funcs[] =
     57      1.1  mrg {
     58      1.1  mrg   mpf_div, mpf_add, mpf_mul, mpf_sub,
     59      1.1  mrg };
     60      1.1  mrg 
     61  1.1.1.2  mrg const char *dss_func_names[] =
     62      1.1  mrg {
     63      1.1  mrg   "mpf_div", "mpf_add", "mpf_mul", "mpf_sub",
     64      1.1  mrg };
     65      1.1  mrg 
     66  1.1.1.2  mrg typedef void (*dsi_func) (mpf_ptr, mpf_srcptr, unsigned long int);
     67      1.1  mrg 
     68      1.1  mrg dsi_func dsi_funcs[] =
     69      1.1  mrg {
     70      1.1  mrg   mpf_div_ui, mpf_add_ui, mpf_mul_ui, mpf_sub_ui,
     71  1.1.1.2  mrg   mpf_mul_2exp, mpf_div_2exp, mpf_pow_ui
     72      1.1  mrg };
     73      1.1  mrg 
     74  1.1.1.2  mrg const char *dsi_func_names[] =
     75      1.1  mrg {
     76      1.1  mrg   "mpf_div_ui", "mpf_add_ui", "mpf_mul_ui", "mpf_sub_ui",
     77  1.1.1.2  mrg   "mpf_mul_2exp", "mpf_div_2exp", "mpf_pow_ui"
     78      1.1  mrg };
     79      1.1  mrg 
     80  1.1.1.2  mrg typedef void (*dis_func) (mpf_ptr, unsigned long int, mpf_srcptr);
     81      1.1  mrg 
     82      1.1  mrg dis_func dis_funcs[] =
     83      1.1  mrg {
     84      1.1  mrg   mpf_ui_div, mpf_ui_sub,
     85      1.1  mrg };
     86      1.1  mrg 
     87  1.1.1.2  mrg const char *dis_func_names[] =
     88      1.1  mrg {
     89      1.1  mrg   "mpf_ui_div", "mpf_ui_sub",
     90      1.1  mrg };
     91      1.1  mrg 
     92      1.1  mrg int
     93      1.1  mrg main (int argc, char **argv)
     94      1.1  mrg {
     95      1.1  mrg   int i;
     96      1.1  mrg   int pass, reps = 10000;
     97      1.1  mrg   mpf_t in1, in2, out1;
     98      1.1  mrg   unsigned long int in1i, in2i;
     99      1.1  mrg   mpf_t res1, res2, res3;
    100      1.1  mrg   mp_size_t bprec = 100;
    101      1.1  mrg 
    102      1.1  mrg   tests_start ();
    103      1.1  mrg 
    104      1.1  mrg   if (argc > 1)
    105      1.1  mrg     {
    106      1.1  mrg       reps = strtol (argv[1], 0, 0);
    107      1.1  mrg       if (argc > 2)
    108      1.1  mrg 	bprec = strtol (argv[2], 0, 0);
    109      1.1  mrg     }
    110      1.1  mrg 
    111      1.1  mrg   mpf_set_default_prec (bprec);
    112      1.1  mrg 
    113      1.1  mrg   mpf_init (in1);
    114      1.1  mrg   mpf_init (in2);
    115      1.1  mrg   mpf_init (out1);
    116      1.1  mrg   mpf_init (res1);
    117      1.1  mrg   mpf_init (res2);
    118      1.1  mrg   mpf_init (res3);
    119      1.1  mrg 
    120      1.1  mrg   for (pass = 1; pass <= reps; pass++)
    121      1.1  mrg     {
    122      1.1  mrg       mpf_random2 (in1, urandom () % SIZE - SIZE/2, urandom () % EXPO);
    123      1.1  mrg       mpf_random2 (in2, urandom () % SIZE - SIZE/2, urandom () % EXPO);
    124      1.1  mrg 
    125      1.1  mrg       for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
    126      1.1  mrg 	{
    127      1.1  mrg 	  /* Don't divide by 0.  */
    128      1.1  mrg 	  if (i == 0 && mpf_cmp_ui (in2, 0) == 0)
    129      1.1  mrg 	    continue;
    130      1.1  mrg 
    131      1.1  mrg 	  (dss_funcs[i]) (res1, in1, in2);
    132      1.1  mrg 
    133      1.1  mrg 	  mpf_set (out1, in1);
    134      1.1  mrg 	  (dss_funcs[i]) (out1, out1, in2);
    135      1.1  mrg 	  mpf_set (res2, out1);
    136      1.1  mrg 
    137      1.1  mrg 	  mpf_set (out1, in2);
    138      1.1  mrg 	  (dss_funcs[i]) (out1, in1, out1);
    139      1.1  mrg 	  mpf_set (res3, out1);
    140      1.1  mrg 
    141      1.1  mrg 	  if (mpf_cmp (res1, res2) != 0)
    142      1.1  mrg 	    dump_abort (dss_func_names[i], res1, res2);
    143      1.1  mrg 	  if (mpf_cmp (res1, res3) != 0)
    144      1.1  mrg 	    dump_abort (dss_func_names[i], res1, res3);
    145      1.1  mrg 	}
    146      1.1  mrg 
    147      1.1  mrg       in2i = urandom ();
    148      1.1  mrg       for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
    149      1.1  mrg 	{
    150  1.1.1.3  mrg 	  unsigned long this_in2i = in2i;
    151  1.1.1.3  mrg 
    152      1.1  mrg 	  /* Don't divide by 0.  */
    153  1.1.1.3  mrg 	  if (dsi_funcs[i] == mpf_div_ui && this_in2i == 0)
    154      1.1  mrg 	    continue;
    155      1.1  mrg 
    156  1.1.1.3  mrg 	  /* Avoid overflow/underflow in the exponent.  */
    157  1.1.1.3  mrg 	  if (dsi_funcs[i] == mpf_mul_2exp || dsi_funcs[i] == mpf_div_2exp)
    158  1.1.1.3  mrg 	    this_in2i %= 0x100000;
    159  1.1.1.3  mrg 	  else if (dsi_funcs[i] == mpf_pow_ui)
    160  1.1.1.3  mrg 	    this_in2i %= 0x1000;
    161  1.1.1.3  mrg 
    162  1.1.1.3  mrg 	  (dsi_funcs[i]) (res1, in1, this_in2i);
    163      1.1  mrg 
    164      1.1  mrg 	  mpf_set (out1, in1);
    165  1.1.1.3  mrg 	  (dsi_funcs[i]) (out1, out1, this_in2i);
    166      1.1  mrg 	  mpf_set (res2, out1);
    167      1.1  mrg 
    168      1.1  mrg 	  if (mpf_cmp (res1, res2) != 0)
    169      1.1  mrg 	    dump_abort (dsi_func_names[i], res1, res2);
    170      1.1  mrg 	}
    171      1.1  mrg 
    172      1.1  mrg       in1i = urandom ();
    173      1.1  mrg       for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++)
    174      1.1  mrg 	{
    175      1.1  mrg 	  /* Don't divide by 0.  */
    176  1.1.1.3  mrg 	  if (dis_funcs[i] == mpf_ui_div
    177      1.1  mrg 	      && mpf_cmp_ui (in2, 0) == 0)
    178      1.1  mrg 	    continue;
    179      1.1  mrg 
    180      1.1  mrg 	  (dis_funcs[i]) (res1, in1i, in2);
    181      1.1  mrg 
    182      1.1  mrg 	  mpf_set (out1, in2);
    183      1.1  mrg 	  (dis_funcs[i]) (out1, in1i, out1);
    184      1.1  mrg 	  mpf_set (res2, out1);
    185      1.1  mrg 
    186      1.1  mrg 	  if (mpf_cmp (res1, res2) != 0)
    187      1.1  mrg 	    dump_abort (dis_func_names[i], res1, res2);
    188      1.1  mrg 	}
    189      1.1  mrg 
    190      1.1  mrg     }
    191      1.1  mrg 
    192      1.1  mrg   mpf_clear (in1);
    193      1.1  mrg   mpf_clear (in2);
    194      1.1  mrg   mpf_clear (out1);
    195      1.1  mrg   mpf_clear (res1);
    196      1.1  mrg   mpf_clear (res2);
    197      1.1  mrg   mpf_clear (res3);
    198      1.1  mrg 
    199      1.1  mrg   tests_end ();
    200      1.1  mrg   exit (0);
    201      1.1  mrg }
    202      1.1  mrg 
    203      1.1  mrg void
    204  1.1.1.2  mrg dump_abort (const char *name, mpf_t res1, mpf_t res2)
    205      1.1  mrg {
    206      1.1  mrg   printf ("failure in %s:\n", name);
    207      1.1  mrg   mpf_dump (res1);
    208      1.1  mrg   mpf_dump (res2);
    209      1.1  mrg   abort ();
    210      1.1  mrg }
    211      1.1  mrg 
    212      1.1  mrg #if 0
    213  1.1.1.2  mrg void mpf_abs		(mpf_ptr, mpf_srcptr);
    214  1.1.1.2  mrg void mpf_sqrt		(mpf_ptr, mpf_srcptr);
    215  1.1.1.2  mrg void mpf_neg		(mpf_ptr, mpf_srcptr);
    216      1.1  mrg #endif
    217      1.1  mrg 
    218      1.1  mrg #endif /* ! DLL_EXPORT */
    219