Upload Tizen:Base source
[external/gmp.git] / tests / mpz / t-aorsmul.c
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 }