1 /* Test that routines allow reusing a source variable as destination. 2 3 Copyright 1996, 2000, 2001, 2002 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library. 6 7 The GNU MP Library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU Lesser General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The GNU MP Library is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 License for more details. 16 17 You should have received a copy of the GNU Lesser General Public License 18 along 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 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 __GMP_PROTO ((char *, mpf_t, mpf_t)); 54 55 typedef void (*dss_func) __GMP_PROTO ((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 char *dss_func_names[] = 63 { 64 "mpf_div", "mpf_add", "mpf_mul", "mpf_sub", 65 }; 66 67 typedef void (*dsi_func) __GMP_PROTO ((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 73 }; 74 75 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" 79 }; 80 81 typedef void (*dis_func) __GMP_PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); 82 83 dis_func dis_funcs[] = 84 { 85 mpf_ui_div, mpf_ui_sub, 86 }; 87 88 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 /* 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 196 void 197 dump_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 206 void mpf_abs __GMP_PROTO ((mpf_ptr, mpf_srcptr)); 207 void mpf_sqrt __GMP_PROTO ((mpf_ptr, mpf_srcptr)); 208 void mpf_neg __GMP_PROTO ((mpf_ptr, mpf_srcptr)); 209 #endif 210 211 #endif /* ! DLL_EXPORT */ 212