github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpf/reuse.c (about) 1 /* Test that routines allow reusing a source variable as destination. 2 3 Copyright 1996, 2000-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 https://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 (const char *, mpf_t, mpf_t); 54 55 typedef void (*dss_func) (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 const char *dss_func_names[] = 63 { 64 "mpf_div", "mpf_add", "mpf_mul", "mpf_sub", 65 }; 66 67 typedef void (*dsi_func) (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, mpf_pow_ui 73 }; 74 75 const 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", "mpf_pow_ui" 79 }; 80 81 typedef void (*dis_func) (mpf_ptr, unsigned long int, mpf_srcptr); 82 83 dis_func dis_funcs[] = 84 { 85 mpf_ui_div, mpf_ui_sub, 86 }; 87 88 const 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 unsigned long this_in2i = in2i; 152 153 /* Don't divide by 0. */ 154 if (dsi_funcs[i] == mpf_div_ui && this_in2i == 0) 155 continue; 156 157 /* Avoid overflow/underflow in the exponent. */ 158 if (dsi_funcs[i] == mpf_mul_2exp || dsi_funcs[i] == mpf_div_2exp) 159 this_in2i %= 0x100000; 160 else if (dsi_funcs[i] == mpf_pow_ui) 161 this_in2i %= 0x1000; 162 163 (dsi_funcs[i]) (res1, in1, this_in2i); 164 165 mpf_set (out1, in1); 166 (dsi_funcs[i]) (out1, out1, this_in2i); 167 mpf_set (res2, out1); 168 169 if (mpf_cmp (res1, res2) != 0) 170 dump_abort (dsi_func_names[i], res1, res2); 171 } 172 173 in1i = urandom (); 174 for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++) 175 { 176 /* Don't divide by 0. */ 177 if (dis_funcs[i] == mpf_ui_div 178 && mpf_cmp_ui (in2, 0) == 0) 179 continue; 180 181 (dis_funcs[i]) (res1, in1i, in2); 182 183 mpf_set (out1, in2); 184 (dis_funcs[i]) (out1, in1i, out1); 185 mpf_set (res2, out1); 186 187 if (mpf_cmp (res1, res2) != 0) 188 dump_abort (dis_func_names[i], res1, res2); 189 } 190 191 } 192 193 mpf_clear (in1); 194 mpf_clear (in2); 195 mpf_clear (out1); 196 mpf_clear (res1); 197 mpf_clear (res2); 198 mpf_clear (res3); 199 200 tests_end (); 201 exit (0); 202 } 203 204 void 205 dump_abort (const char *name, mpf_t res1, mpf_t res2) 206 { 207 printf ("failure in %s:\n", name); 208 mpf_dump (res1); 209 mpf_dump (res2); 210 abort (); 211 } 212 213 #if 0 214 void mpf_abs (mpf_ptr, mpf_srcptr); 215 void mpf_sqrt (mpf_ptr, mpf_srcptr); 216 void mpf_neg (mpf_ptr, mpf_srcptr); 217 #endif 218 219 #endif /* ! DLL_EXPORT */