1 /* Test that routines allow reusing a source variable as destination. 2 3 Copyright 1996, 2000-2002, 2012, 2015 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 https://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 #if __GMP_LIBGMP_DLL 28 29 /* FIXME: When linking to a DLL libgmp, mpq_add etc can't be used as 30 initializers for global variables because they're effectively global 31 variables (function pointers) themselves. Perhaps calling a test 32 function successively with mpq_add etc would be better. */ 33 34 int 35 main (void) 36 { 37 printf ("Test suppressed for windows DLL\n"); 38 exit (0); 39 } 40 41 42 #else /* ! DLL_EXPORT */ 43 44 #ifndef SIZE 45 #define SIZE 16 46 #endif 47 48 void dump_abort (const char *, mpq_t, mpq_t); 49 50 typedef void (*dss_func) (mpq_ptr, mpq_srcptr, mpq_srcptr); 51 52 dss_func dss_funcs[] = 53 { 54 mpq_div, mpq_add, mpq_mul, mpq_sub, 55 }; 56 57 const char *dss_func_names[] = 58 { 59 "mpq_div", "mpq_add", "mpq_mul", "mpq_sub", 60 }; 61 62 typedef void (*ds_func) (mpq_ptr, mpq_srcptr); 63 64 ds_func ds_funcs[] = 65 { 66 mpq_abs, mpq_neg, 67 }; 68 69 const char *ds_func_names[] = 70 { 71 "mpq_abs", "mpq_neg", 72 }; 73 74 typedef void (*dsi_func) (mpq_ptr, mpq_srcptr, unsigned long int); 75 76 dsi_func dsi_funcs[] = 77 { 78 mpq_mul_2exp, mpq_div_2exp 79 }; 80 81 const char *dsi_func_names[] = 82 { 83 "mpq_mul_2exp", "mpq_div_2exp" 84 }; 85 86 int 87 main (int argc, char **argv) 88 { 89 int i; 90 int pass, reps = 100; 91 mpq_t in1, in2, out1; 92 unsigned long int randbits, in2i; 93 mpq_t res1, res2; 94 gmp_randstate_ptr rands; 95 96 tests_start (); 97 98 TESTS_REPS (reps, argv, argc); 99 100 rands = RANDS; 101 102 mpq_init (in1); 103 mpq_init (in2); 104 mpq_init (out1); 105 mpq_init (res1); 106 mpq_init (res2); 107 108 for (pass = 1; pass <= reps; pass++) 109 { 110 randbits = urandom (); 111 112 if (randbits & 1) 113 { 114 mpq_clear (in1); 115 mpq_init (in1); 116 } 117 randbits >>= 1; 118 mpz_errandomb (mpq_numref(in1), rands, 512L); 119 mpz_errandomb_nonzero (mpq_denref(in1), rands, 512L); 120 if (randbits & 1) 121 mpz_neg (mpq_numref(in1),mpq_numref(in1)); 122 randbits >>= 1; 123 mpq_canonicalize (in1); 124 125 if (randbits & 1) 126 { 127 mpq_clear (in2); 128 mpq_init (in2); 129 } 130 randbits >>= 1; 131 mpz_errandomb (mpq_numref(in2), rands, 512L); 132 mpz_errandomb_nonzero (mpq_denref(in2), rands, 512L); 133 if (randbits & 1) 134 mpz_neg (mpq_numref(in2),mpq_numref(in2)); 135 randbits >>= 1; 136 mpq_canonicalize (in2); 137 138 for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++) 139 { 140 /* Don't divide by 0. */ 141 if (i == 0 && mpq_cmp_ui (in2, 0, 1) == 0) 142 continue; 143 144 if (randbits & 1) 145 { 146 mpq_clear (res1); 147 mpq_init (res1); 148 } 149 randbits >>= 1; 150 151 (dss_funcs[i]) (res1, in1, in2); 152 MPQ_CHECK_FORMAT(res1); 153 154 mpq_set (out1, in1); 155 (dss_funcs[i]) (out1, out1, in2); 156 MPQ_CHECK_FORMAT(out1); 157 158 if (mpq_cmp (res1, out1) != 0) 159 dump_abort (dss_func_names[i], res1, out1); 160 161 mpq_set (out1, in2); 162 (dss_funcs[i]) (out1, in1, out1); 163 MPQ_CHECK_FORMAT(out1); 164 165 if (mpq_cmp (res1, out1) != 0) 166 dump_abort (dss_func_names[i], res1, out1); 167 168 mpq_set (out1, in2); 169 (dss_funcs[i]) (res1, out1, in2); 170 MPQ_CHECK_FORMAT(res1); 171 172 (dss_funcs[i]) (res2, in2, in2); 173 MPQ_CHECK_FORMAT(res2); 174 175 (dss_funcs[i]) (out1, out1, out1); 176 MPQ_CHECK_FORMAT(out1); 177 178 if (mpq_cmp (res1, res2) != 0) 179 dump_abort (dss_func_names[i], res1, res2); 180 if (mpq_cmp (res1, out1) != 0) 181 dump_abort (dss_func_names[i], res1, out1); 182 } 183 184 for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++) 185 { 186 if (randbits & 1) 187 { 188 mpq_clear (res1); 189 mpq_init (res1); 190 } 191 randbits >>= 1; 192 (ds_funcs[i]) (res1, in1); 193 MPQ_CHECK_FORMAT(res1); 194 195 mpq_set (out1, in1); 196 (ds_funcs[i]) (out1, out1); 197 MPQ_CHECK_FORMAT(out1); 198 199 if (mpq_cmp (res1, out1) != 0) 200 dump_abort (ds_func_names[i], res1, out1); 201 } 202 203 in2i = urandom () % 65536; 204 for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++) 205 { 206 if (randbits & 1) 207 { 208 mpq_clear (res1); 209 mpq_init (res1); 210 } 211 randbits >>= 1; 212 213 (dsi_funcs[i]) (res1, in1, in2i); 214 MPQ_CHECK_FORMAT(res1); 215 216 mpq_set (out1, in1); 217 (dsi_funcs[i]) (out1, out1, in2i); 218 MPQ_CHECK_FORMAT(out1); 219 220 if (mpq_cmp (res1, out1) != 0) 221 dump_abort (dsi_func_names[i], res1, out1); 222 } 223 224 } 225 226 mpq_clear (in1); 227 mpq_clear (in2); 228 mpq_clear (out1); 229 mpq_clear (res1); 230 mpq_clear (res2); 231 232 tests_end (); 233 exit (0); 234 } 235 236 void 237 dump_abort (const char *name, mpq_t res1, mpq_t res2) 238 { 239 printf ("failure in %s:\n", name); 240 mpq_trace (" res1 ", res1); 241 mpq_trace (" res2 ", res2); 242 abort (); 243 } 244 245 #endif /* ! DLL_EXPORT */ 246