1 /* Test that routines allow reusing a source variable as destination. 2 3 Copyright 1996, 2000, 2001, 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 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, mpq_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 mpq_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 void dump_abort (const char *, mpq_t, mpq_t); 50 51 typedef void (*dss_func) (mpq_ptr, mpq_srcptr, mpq_srcptr); 52 53 dss_func dss_funcs[] = 54 { 55 mpq_div, mpq_add, mpq_mul, mpq_sub, 56 }; 57 58 const char *dss_func_names[] = 59 { 60 "mpq_div", "mpq_add", "mpq_mul", "mpq_sub", 61 }; 62 63 typedef void (*ds_func) (mpq_ptr, mpq_srcptr); 64 65 ds_func ds_funcs[] = 66 { 67 mpq_abs, mpq_neg, 68 }; 69 70 const char *ds_func_names[] = 71 { 72 "mpq_abs", "mpq_neg", 73 }; 74 75 typedef void (*dsi_func) (mpq_ptr, mpq_srcptr, unsigned long int); 76 77 dsi_func dsi_funcs[] = 78 { 79 mpq_mul_2exp, mpq_div_2exp 80 }; 81 82 const char *dsi_func_names[] = 83 { 84 "mpq_mul_2exp", "mpq_div_2exp" 85 }; 86 87 int 88 main (int argc, char **argv) 89 { 90 int i; 91 int pass, reps = 100; 92 mpq_t in1, in2, out1; 93 unsigned long int randbits, in2i; 94 mpq_t res1, res2, res3; 95 gmp_randstate_ptr rands; 96 97 tests_start (); 98 99 if (argc > 1) 100 reps = strtol (argv[1], 0, 0); 101 102 rands = RANDS; 103 104 mpq_init (in1); 105 mpq_init (in2); 106 mpq_init (out1); 107 mpq_init (res1); 108 mpq_init (res2); 109 mpq_init (res3); 110 111 for (pass = 1; pass <= reps; pass++) 112 { 113 randbits = urandom (); 114 115 if (randbits & 1) 116 { 117 mpq_clear (in1); 118 mpq_init (in1); 119 } 120 randbits >>= 1; 121 mpz_errandomb (mpq_numref(in1), rands, 512L); 122 mpz_errandomb_nonzero (mpq_denref(in1), rands, 512L); 123 if (randbits & 1) 124 mpz_neg (mpq_numref(in1),mpq_numref(in1)); 125 randbits >>= 1; 126 mpq_canonicalize (in1); 127 128 if (randbits & 1) 129 { 130 mpq_clear (in2); 131 mpq_init (in2); 132 } 133 randbits >>= 1; 134 mpz_errandomb (mpq_numref(in2), rands, 512L); 135 mpz_errandomb_nonzero (mpq_denref(in2), rands, 512L); 136 if (randbits & 1) 137 mpz_neg (mpq_numref(in2),mpq_numref(in2)); 138 randbits >>= 1; 139 mpq_canonicalize (in2); 140 141 for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++) 142 { 143 /* Don't divide by 0. */ 144 if (i == 0 && mpq_cmp_ui (in2, 0, 1) == 0) 145 continue; 146 147 if (randbits & 1) 148 { 149 mpq_clear (res1); 150 mpq_init (res1); 151 } 152 randbits >>= 1; 153 154 (dss_funcs[i]) (res1, in1, in2); 155 156 mpq_set (out1, in1); 157 (dss_funcs[i]) (out1, out1, in2); 158 mpq_set (res2, out1); 159 160 mpq_set (out1, in2); 161 (dss_funcs[i]) (out1, in1, out1); 162 mpq_set (res3, out1); 163 164 if (mpq_cmp (res1, res2) != 0) 165 dump_abort (dss_func_names[i], res1, res2); 166 if (mpq_cmp (res1, res3) != 0) 167 dump_abort (dss_func_names[i], res1, res3); 168 } 169 170 for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++) 171 { 172 if (randbits & 1) 173 { 174 mpq_clear (res1); 175 mpq_init (res1); 176 } 177 randbits >>= 1; 178 (ds_funcs[i]) (res1, in1); 179 180 mpq_set (out1, in1); 181 (ds_funcs[i]) (out1, out1); 182 mpq_set (res2, out1); 183 184 if (mpq_cmp (res1, res2) != 0) 185 dump_abort (ds_func_names[i], res1, res2); 186 } 187 188 in2i = urandom () % 65536; 189 for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++) 190 { 191 if (randbits & 1) 192 { 193 mpq_clear (res1); 194 mpq_init (res1); 195 } 196 randbits >>= 1; 197 198 (dsi_funcs[i]) (res1, in1, in2i); 199 200 mpq_set (out1, in1); 201 (dsi_funcs[i]) (out1, out1, in2i); 202 mpq_set (res2, out1); 203 204 if (mpq_cmp (res1, res2) != 0) 205 dump_abort (dsi_func_names[i], res1, res2); 206 } 207 208 } 209 210 mpq_clear (in1); 211 mpq_clear (in2); 212 mpq_clear (out1); 213 mpq_clear (res1); 214 mpq_clear (res2); 215 mpq_clear (res3); 216 217 tests_end (); 218 exit (0); 219 } 220 221 void 222 dump_abort (const char *name, mpq_t res1, mpq_t res2) 223 { 224 printf ("failure in %s:\n", name); 225 mpq_trace (" res1 ", res1); 226 mpq_trace (" res2 ", res2); 227 abort (); 228 } 229 230 #endif /* ! DLL_EXPORT */ 231