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