t-aorsmul.c revision 1.1.1.1 1 1.1 mrg /* Test mpz_addmul, mpz_addmul_ui, mpz_submul, mpz_submul_ui.
2 1.1 mrg
3 1.1 mrg Copyright 2001, 2002 Free Software Foundation, Inc.
4 1.1 mrg
5 1.1 mrg This file is part of the GNU MP Library.
6 1.1 mrg
7 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify
8 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
9 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
10 1.1 mrg option) any later version.
11 1.1 mrg
12 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but
13 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 1.1 mrg License for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU Lesser General Public License
18 1.1 mrg along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
19 1.1 mrg
20 1.1 mrg
21 1.1 mrg #include <stdio.h>
22 1.1 mrg #include <stdlib.h>
23 1.1 mrg #include <string.h>
24 1.1 mrg
25 1.1 mrg #include "gmp.h"
26 1.1 mrg #include "gmp-impl.h"
27 1.1 mrg #include "tests.h"
28 1.1 mrg
29 1.1 mrg
30 1.1 mrg #define M GMP_NUMB_MAX
31 1.1 mrg
32 1.1 mrg
33 1.1 mrg void
34 1.1 mrg check_one_inplace (mpz_srcptr w, mpz_srcptr y)
35 1.1 mrg {
36 1.1 mrg mpz_t want, got;
37 1.1 mrg
38 1.1 mrg mpz_init (want);
39 1.1 mrg mpz_init (got);
40 1.1 mrg
41 1.1 mrg mpz_mul (want, w, y);
42 1.1 mrg mpz_add (want, w, want);
43 1.1 mrg mpz_set (got, w);
44 1.1 mrg mpz_addmul (got, got, y);
45 1.1 mrg MPZ_CHECK_FORMAT (got);
46 1.1 mrg if (mpz_cmp (want, got) != 0)
47 1.1 mrg {
48 1.1 mrg printf ("mpz_addmul inplace fail\n");
49 1.1 mrg fail:
50 1.1 mrg mpz_trace ("w", w);
51 1.1 mrg mpz_trace ("y", y);
52 1.1 mrg mpz_trace ("want", want);
53 1.1 mrg mpz_trace ("got ", got);
54 1.1 mrg abort ();
55 1.1 mrg }
56 1.1 mrg
57 1.1 mrg mpz_mul (want, w, y);
58 1.1 mrg mpz_sub (want, w, want);
59 1.1 mrg mpz_set (got, w);
60 1.1 mrg mpz_submul (got, got, y);
61 1.1 mrg MPZ_CHECK_FORMAT (got);
62 1.1 mrg if (mpz_cmp (want, got) != 0)
63 1.1 mrg {
64 1.1 mrg printf ("mpz_submul inplace fail\n");
65 1.1 mrg goto fail;
66 1.1 mrg }
67 1.1 mrg
68 1.1 mrg mpz_clear (want);
69 1.1 mrg mpz_clear (got);
70 1.1 mrg }
71 1.1 mrg
72 1.1 mrg void
73 1.1 mrg check_one_ui_inplace (mpz_ptr w, unsigned long y)
74 1.1 mrg {
75 1.1 mrg mpz_t want, got;
76 1.1 mrg
77 1.1 mrg mpz_init (want);
78 1.1 mrg mpz_init (got);
79 1.1 mrg
80 1.1 mrg mpz_mul_ui (want, w, (unsigned long) y);
81 1.1 mrg mpz_add (want, w, want);
82 1.1 mrg mpz_set (got, w);
83 1.1 mrg mpz_addmul_ui (got, got, (unsigned long) y);
84 1.1 mrg MPZ_CHECK_FORMAT (got);
85 1.1 mrg if (mpz_cmp (want, got) != 0)
86 1.1 mrg {
87 1.1 mrg printf ("mpz_addmul_ui fail\n");
88 1.1 mrg fail:
89 1.1 mrg mpz_trace ("w", w);
90 1.1 mrg printf ("y=0x%lX %lu\n", y, y);
91 1.1 mrg mpz_trace ("want", want);
92 1.1 mrg mpz_trace ("got ", got);
93 1.1 mrg abort ();
94 1.1 mrg }
95 1.1 mrg
96 1.1 mrg mpz_mul_ui (want, w, y);
97 1.1 mrg mpz_sub (want, w, want);
98 1.1 mrg mpz_set (got, w);
99 1.1 mrg mpz_submul_ui (got, got, y);
100 1.1 mrg MPZ_CHECK_FORMAT (got);
101 1.1 mrg if (mpz_cmp (want, got) != 0)
102 1.1 mrg {
103 1.1 mrg printf ("mpz_submul_ui fail\n");
104 1.1 mrg goto fail;
105 1.1 mrg }
106 1.1 mrg
107 1.1 mrg mpz_clear (want);
108 1.1 mrg mpz_clear (got);
109 1.1 mrg }
110 1.1 mrg
111 1.1 mrg void
112 1.1 mrg check_all_inplace (mpz_ptr w, mpz_ptr y)
113 1.1 mrg {
114 1.1 mrg int wneg, yneg;
115 1.1 mrg
116 1.1 mrg MPZ_CHECK_FORMAT (w);
117 1.1 mrg MPZ_CHECK_FORMAT (y);
118 1.1 mrg
119 1.1 mrg for (wneg = 0; wneg < 2; wneg++)
120 1.1 mrg {
121 1.1 mrg for (yneg = 0; yneg < 2; yneg++)
122 1.1 mrg {
123 1.1 mrg check_one_inplace (w, y);
124 1.1 mrg
125 1.1 mrg if (mpz_fits_ulong_p (y))
126 1.1 mrg check_one_ui_inplace (w, mpz_get_ui (y));
127 1.1 mrg
128 1.1 mrg mpz_neg (y, y);
129 1.1 mrg }
130 1.1 mrg mpz_neg (w, w);
131 1.1 mrg }
132 1.1 mrg }
133 1.1 mrg
134 1.1 mrg void
135 1.1 mrg check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y)
136 1.1 mrg {
137 1.1 mrg mpz_t want, got;
138 1.1 mrg
139 1.1 mrg mpz_init (want);
140 1.1 mrg mpz_init (got);
141 1.1 mrg
142 1.1 mrg mpz_mul (want, x, y);
143 1.1 mrg mpz_add (want, w, want);
144 1.1 mrg mpz_set (got, w);
145 1.1 mrg mpz_addmul (got, x, y);
146 1.1 mrg MPZ_CHECK_FORMAT (got);
147 1.1 mrg if (mpz_cmp (want, got) != 0)
148 1.1 mrg {
149 1.1 mrg printf ("mpz_addmul fail\n");
150 1.1 mrg fail:
151 1.1 mrg mpz_trace ("w", w);
152 1.1 mrg mpz_trace ("x", x);
153 1.1 mrg mpz_trace ("y", y);
154 1.1 mrg mpz_trace ("want", want);
155 1.1 mrg mpz_trace ("got ", got);
156 1.1 mrg abort ();
157 1.1 mrg }
158 1.1 mrg
159 1.1 mrg mpz_mul (want, x, y);
160 1.1 mrg mpz_sub (want, w, want);
161 1.1 mrg mpz_set (got, w);
162 1.1 mrg mpz_submul (got, x, y);
163 1.1 mrg MPZ_CHECK_FORMAT (got);
164 1.1 mrg if (mpz_cmp (want, got) != 0)
165 1.1 mrg {
166 1.1 mrg printf ("mpz_submul fail\n");
167 1.1 mrg goto fail;
168 1.1 mrg }
169 1.1 mrg
170 1.1 mrg mpz_clear (want);
171 1.1 mrg mpz_clear (got);
172 1.1 mrg }
173 1.1 mrg
174 1.1 mrg void
175 1.1 mrg check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y)
176 1.1 mrg {
177 1.1 mrg mpz_t want, got;
178 1.1 mrg
179 1.1 mrg mpz_init (want);
180 1.1 mrg mpz_init (got);
181 1.1 mrg
182 1.1 mrg mpz_mul_ui (want, x, (unsigned long) y);
183 1.1 mrg mpz_add (want, w, want);
184 1.1 mrg mpz_set (got, w);
185 1.1 mrg mpz_addmul_ui (got, x, (unsigned long) y);
186 1.1 mrg MPZ_CHECK_FORMAT (got);
187 1.1 mrg if (mpz_cmp (want, got) != 0)
188 1.1 mrg {
189 1.1 mrg printf ("mpz_addmul_ui fail\n");
190 1.1 mrg fail:
191 1.1 mrg mpz_trace ("w", w);
192 1.1 mrg mpz_trace ("x", x);
193 1.1 mrg printf ("y=0x%lX %lu\n", y, y);
194 1.1 mrg mpz_trace ("want", want);
195 1.1 mrg mpz_trace ("got ", got);
196 1.1 mrg abort ();
197 1.1 mrg }
198 1.1 mrg
199 1.1 mrg mpz_mul_ui (want, x, y);
200 1.1 mrg mpz_sub (want, w, want);
201 1.1 mrg mpz_set (got, w);
202 1.1 mrg mpz_submul_ui (got, x, y);
203 1.1 mrg MPZ_CHECK_FORMAT (got);
204 1.1 mrg if (mpz_cmp (want, got) != 0)
205 1.1 mrg {
206 1.1 mrg printf ("mpz_submul_ui fail\n");
207 1.1 mrg goto fail;
208 1.1 mrg }
209 1.1 mrg
210 1.1 mrg mpz_clear (want);
211 1.1 mrg mpz_clear (got);
212 1.1 mrg }
213 1.1 mrg
214 1.1 mrg
215 1.1 mrg void
216 1.1 mrg check_all (mpz_ptr w, mpz_ptr x, mpz_ptr y)
217 1.1 mrg {
218 1.1 mrg int swap, wneg, xneg, yneg;
219 1.1 mrg
220 1.1 mrg MPZ_CHECK_FORMAT (w);
221 1.1 mrg MPZ_CHECK_FORMAT (x);
222 1.1 mrg MPZ_CHECK_FORMAT (y);
223 1.1 mrg
224 1.1 mrg for (swap = 0; swap < 2; swap++)
225 1.1 mrg {
226 1.1 mrg for (wneg = 0; wneg < 2; wneg++)
227 1.1 mrg {
228 1.1 mrg for (xneg = 0; xneg < 2; xneg++)
229 1.1 mrg {
230 1.1 mrg for (yneg = 0; yneg < 2; yneg++)
231 1.1 mrg {
232 1.1 mrg check_one (w, x, y);
233 1.1 mrg
234 1.1 mrg if (mpz_fits_ulong_p (y))
235 1.1 mrg check_one_ui (w, x, mpz_get_ui (y));
236 1.1 mrg
237 1.1 mrg mpz_neg (y, y);
238 1.1 mrg }
239 1.1 mrg mpz_neg (x, x);
240 1.1 mrg }
241 1.1 mrg mpz_neg (w, w);
242 1.1 mrg }
243 1.1 mrg mpz_swap (x, y);
244 1.1 mrg }
245 1.1 mrg }
246 1.1 mrg
247 1.1 mrg void
248 1.1 mrg check_data_inplace_ui (void)
249 1.1 mrg {
250 1.1 mrg static const struct {
251 1.1 mrg mp_limb_t w[6];
252 1.1 mrg unsigned long y;
253 1.1 mrg
254 1.1 mrg } data[] = {
255 1.1 mrg
256 1.1 mrg { { 0 }, 0 },
257 1.1 mrg { { 0 }, 1 },
258 1.1 mrg { { 1 }, 1 },
259 1.1 mrg { { 2 }, 1 },
260 1.1 mrg
261 1.1 mrg { { 123 }, 1 },
262 1.1 mrg { { 123 }, ULONG_MAX },
263 1.1 mrg { { M }, 1 },
264 1.1 mrg { { M }, ULONG_MAX },
265 1.1 mrg
266 1.1 mrg { { 123, 456 }, 1 },
267 1.1 mrg { { M, M }, 1 },
268 1.1 mrg { { 123, 456 }, ULONG_MAX },
269 1.1 mrg { { M, M }, ULONG_MAX },
270 1.1 mrg
271 1.1 mrg { { 123, 456, 789 }, 1 },
272 1.1 mrg { { M, M, M }, 1 },
273 1.1 mrg { { 123, 456, 789 }, ULONG_MAX },
274 1.1 mrg { { M, M, M }, ULONG_MAX },
275 1.1 mrg };
276 1.1 mrg
277 1.1 mrg mpz_t w, y;
278 1.1 mrg int i;
279 1.1 mrg
280 1.1 mrg mpz_init (w);
281 1.1 mrg mpz_init (y);
282 1.1 mrg
283 1.1 mrg for (i = 0; i < numberof (data); i++)
284 1.1 mrg {
285 1.1 mrg mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w));
286 1.1 mrg mpz_set_ui (y, data[i].y);
287 1.1 mrg check_all_inplace (w, y);
288 1.1 mrg }
289 1.1 mrg
290 1.1 mrg mpz_clear (w);
291 1.1 mrg mpz_clear (y);
292 1.1 mrg }
293 1.1 mrg
294 1.1 mrg void
295 1.1 mrg check_data (void)
296 1.1 mrg {
297 1.1 mrg static const struct {
298 1.1 mrg mp_limb_t w[6];
299 1.1 mrg mp_limb_t x[6];
300 1.1 mrg mp_limb_t y[6];
301 1.1 mrg
302 1.1 mrg } data[] = {
303 1.1 mrg
304 1.1 mrg /* reducing to zero */
305 1.1 mrg { { 1 }, { 1 }, { 1 } },
306 1.1 mrg { { 2 }, { 1 }, { 2 } },
307 1.1 mrg { { 0,1 }, { 0,1 }, { 1 } },
308 1.1 mrg
309 1.1 mrg /* reducing to 1 */
310 1.1 mrg { { 0,1 }, { M }, { 1 } },
311 1.1 mrg { { 0,0,1 }, { M,M }, { 1 } },
312 1.1 mrg { { 0,0,0,1 }, { M,M,M }, { 1 } },
313 1.1 mrg { { 0,0,0,0,1 }, { M,M,M,M }, { 1 } },
314 1.1 mrg
315 1.1 mrg /* reducing to -1 */
316 1.1 mrg { { M }, { 0,1 }, { 1 } },
317 1.1 mrg { { M,M }, { 0,0,1 }, { 1 } },
318 1.1 mrg { { M,M,M }, { 0,0,0,1 }, { 1 } },
319 1.1 mrg { { M,M,M,M }, { 0,0,0,0,1 }, { 1 } },
320 1.1 mrg
321 1.1 mrg /* carry out of addmul */
322 1.1 mrg { { M }, { 1 }, { 1 } },
323 1.1 mrg { { M,M }, { 1 }, { 1 } },
324 1.1 mrg { { M,M,M }, { 1 }, { 1 } },
325 1.1 mrg
326 1.1 mrg /* borrow from submul */
327 1.1 mrg { { 0,1 }, { 1 }, { 1 } },
328 1.1 mrg { { 0,0,1 }, { 1 }, { 1 } },
329 1.1 mrg { { 0,0,0,1 }, { 1 }, { 1 } },
330 1.1 mrg
331 1.1 mrg /* borrow from submul */
332 1.1 mrg { { 0,0,1 }, { 0,1 }, { 1 } },
333 1.1 mrg { { 0,0,0,1 }, { 0,1 }, { 1 } },
334 1.1 mrg { { 0,0,0,0,1 }, { 0,1 }, { 1 } },
335 1.1 mrg
336 1.1 mrg /* more borrow from submul */
337 1.1 mrg { { M }, { 0,1 }, { 1 } },
338 1.1 mrg { { M }, { 0,0,1 }, { 1 } },
339 1.1 mrg { { M }, { 0,0,0,1 }, { 1 } },
340 1.1 mrg { { M }, { 0,0,0,0,1 }, { 1 } },
341 1.1 mrg
342 1.1 mrg /* big borrow from submul */
343 1.1 mrg { { 0,0,1 }, { M,M }, { M } },
344 1.1 mrg { { 0,0,0,1 }, { M,M }, { M } },
345 1.1 mrg { { 0,0,0,0,1 }, { M,M }, { M } },
346 1.1 mrg
347 1.1 mrg /* small w */
348 1.1 mrg { { 0,1 }, { M,M }, { M } },
349 1.1 mrg { { 0,1 }, { M,M,M }, { M } },
350 1.1 mrg { { 0,1 }, { M,M,M,M }, { M } },
351 1.1 mrg { { 0,1 }, { M,M,M,M,M }, { M } },
352 1.1 mrg };
353 1.1 mrg
354 1.1 mrg mpz_t w, x, y;
355 1.1 mrg int i;
356 1.1 mrg
357 1.1 mrg mpz_init (w);
358 1.1 mrg mpz_init (x);
359 1.1 mrg mpz_init (y);
360 1.1 mrg
361 1.1 mrg for (i = 0; i < numberof (data); i++)
362 1.1 mrg {
363 1.1 mrg mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w));
364 1.1 mrg mpz_set_n (x, data[i].x, (mp_size_t) numberof(data[i].x));
365 1.1 mrg mpz_set_n (y, data[i].y, (mp_size_t) numberof(data[i].y));
366 1.1 mrg check_all (w, x, y);
367 1.1 mrg }
368 1.1 mrg
369 1.1 mrg mpz_clear (w);
370 1.1 mrg mpz_clear (x);
371 1.1 mrg mpz_clear (y);
372 1.1 mrg }
373 1.1 mrg
374 1.1 mrg
375 1.1 mrg void
376 1.1 mrg check_random (int argc, char *argv[])
377 1.1 mrg {
378 1.1 mrg gmp_randstate_ptr rands = RANDS;
379 1.1 mrg mpz_t w, x, y;
380 1.1 mrg int i, reps = 2000;
381 1.1 mrg
382 1.1 mrg mpz_init (w);
383 1.1 mrg mpz_init (x);
384 1.1 mrg mpz_init (y);
385 1.1 mrg
386 1.1 mrg if (argc == 2)
387 1.1 mrg reps = atoi (argv[1]);
388 1.1 mrg
389 1.1 mrg for (i = 0; i < reps; i++)
390 1.1 mrg {
391 1.1 mrg mpz_errandomb (w, rands, 5*GMP_LIMB_BITS);
392 1.1 mrg mpz_errandomb (x, rands, 5*GMP_LIMB_BITS);
393 1.1 mrg mpz_errandomb (y, rands, 5*GMP_LIMB_BITS);
394 1.1 mrg check_all (w, x, y);
395 1.1 mrg check_all_inplace (w, y);
396 1.1 mrg
397 1.1 mrg mpz_errandomb (w, rands, 5*GMP_LIMB_BITS);
398 1.1 mrg mpz_errandomb (x, rands, 5*GMP_LIMB_BITS);
399 1.1 mrg mpz_errandomb (y, rands, BITS_PER_ULONG);
400 1.1 mrg check_all (w, x, y);
401 1.1 mrg check_all_inplace (w, y);
402 1.1 mrg }
403 1.1 mrg
404 1.1 mrg mpz_clear (w);
405 1.1 mrg mpz_clear (x);
406 1.1 mrg mpz_clear (y);
407 1.1 mrg }
408 1.1 mrg
409 1.1 mrg
410 1.1 mrg int
411 1.1 mrg main (int argc, char *argv[])
412 1.1 mrg {
413 1.1 mrg tests_start ();
414 1.1 mrg mp_trace_base = -16;
415 1.1 mrg
416 1.1 mrg check_data ();
417 1.1 mrg check_data_inplace_ui ();
418 1.1 mrg check_random (argc, argv);
419 1.1 mrg
420 1.1 mrg tests_end ();
421 1.1 mrg exit (0);
422 1.1 mrg }
423