1/* Test that routines allow reusing a source variable as destination. 2 3Copyright 1996, 2000, 2001, 2002 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along with the GNU MP Library. If not, see http://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 35int 36main (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 53void dump_abort __GMP_PROTO ((char *, mpf_t, mpf_t)); 54 55typedef void (*dss_func) __GMP_PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); 56 57dss_func dss_funcs[] = 58{ 59 mpf_div, mpf_add, mpf_mul, mpf_sub, 60}; 61 62char *dss_func_names[] = 63{ 64 "mpf_div", "mpf_add", "mpf_mul", "mpf_sub", 65}; 66 67typedef void (*dsi_func) __GMP_PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); 68 69dsi_func dsi_funcs[] = 70{ 71 mpf_div_ui, mpf_add_ui, mpf_mul_ui, mpf_sub_ui, 72 mpf_mul_2exp, mpf_div_2exp 73}; 74 75char *dsi_func_names[] = 76{ 77 "mpf_div_ui", "mpf_add_ui", "mpf_mul_ui", "mpf_sub_ui", 78 "mpf_mul_2exp", "mpf_div_2exp" 79}; 80 81typedef void (*dis_func) __GMP_PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); 82 83dis_func dis_funcs[] = 84{ 85 mpf_ui_div, mpf_ui_sub, 86}; 87 88char *dis_func_names[] = 89{ 90 "mpf_ui_div", "mpf_ui_sub", 91}; 92 93int 94main (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 /* Don't divide by 0. */ 152 if (strcmp (dsi_func_names[i], "mpf_div_ui") == 0 && in2i == 0) 153 continue; 154 155 (dsi_funcs[i]) (res1, in1, in2i); 156 157 mpf_set (out1, in1); 158 (dsi_funcs[i]) (out1, out1, in2i); 159 mpf_set (res2, out1); 160 161 if (mpf_cmp (res1, res2) != 0) 162 dump_abort (dsi_func_names[i], res1, res2); 163 } 164 165 in1i = urandom (); 166 for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++) 167 { 168 /* Don't divide by 0. */ 169 if (strcmp (dis_func_names[i], "mpf_ui_div") == 0 170 && mpf_cmp_ui (in2, 0) == 0) 171 continue; 172 173 (dis_funcs[i]) (res1, in1i, in2); 174 175 mpf_set (out1, in2); 176 (dis_funcs[i]) (out1, in1i, out1); 177 mpf_set (res2, out1); 178 179 if (mpf_cmp (res1, res2) != 0) 180 dump_abort (dis_func_names[i], res1, res2); 181 } 182 183 } 184 185 mpf_clear (in1); 186 mpf_clear (in2); 187 mpf_clear (out1); 188 mpf_clear (res1); 189 mpf_clear (res2); 190 mpf_clear (res3); 191 192 tests_end (); 193 exit (0); 194} 195 196void 197dump_abort (char *name, mpf_t res1, mpf_t res2) 198{ 199 printf ("failure in %s:\n", name); 200 mpf_dump (res1); 201 mpf_dump (res2); 202 abort (); 203} 204 205#if 0 206void mpf_abs __GMP_PROTO ((mpf_ptr, mpf_srcptr)); 207void mpf_sqrt __GMP_PROTO ((mpf_ptr, mpf_srcptr)); 208void mpf_neg __GMP_PROTO ((mpf_ptr, mpf_srcptr)); 209#endif 210 211#endif /* ! DLL_EXPORT */ 212