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
main(void)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
main(int argc,char ** argv)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
dump_abort(const char * name,mpq_t res1,mpq_t res2)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