xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpq/reuse.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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