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