Upload Tizen:Base source
[external/gmp.git] / tests / mpn / t-mullo.c
1 /* Test for mullo function.
2
3 Copyright 2009 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 "gmp.h"
22 #include "gmp-impl.h"
23 #include "tests.h"
24
25 #include <stdlib.h>
26 #include <stdio.h>
27
28 /* Sizes are up to 2^SIZE_LOG limbs */
29 #ifndef SIZE_LOG
30 #define SIZE_LOG 10
31 #endif
32
33 #ifndef COUNT
34 #define COUNT 10000
35 #endif
36
37 #define MAX_N (1L << SIZE_LOG)
38 #define MIN_N (1)
39
40 int
41 main (int argc, char **argv)
42 {
43   mp_ptr ap, bp, refp, pp, scratch;
44   int count = COUNT;
45   int test;
46   gmp_randstate_ptr rands;
47   TMP_DECL;
48   TMP_MARK;
49
50   if (argc > 1)
51     {
52       char *end;
53       count = strtol (argv[1], &end, 0);
54       if (*end || count <= 0)
55         {
56           fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
57           return 1;
58         }
59     }
60
61   tests_start ();
62   rands = RANDS;
63
64 #define mpn_mullo_itch(n) (0)
65
66   ap = TMP_ALLOC_LIMBS (MAX_N);
67   bp = TMP_ALLOC_LIMBS (MAX_N);
68   refp = TMP_ALLOC_LIMBS (MAX_N * 2);
69   pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
70   scratch
71     = 1+TMP_ALLOC_LIMBS (mpn_mullo_itch (MAX_N) + 2);
72
73   for (test = 0; test < count; test++)
74     {
75       unsigned size_min;
76       unsigned size_range;
77       mp_size_t n;
78       mp_size_t itch;
79       mp_limb_t p_before, p_after, s_before, s_after;
80
81       for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
82         ;
83
84       /* We generate an in the MIN_N <= n <= (1 << size_range). */
85       size_range = size_min
86         + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
87
88       n = MIN_N
89         + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
90
91       mpn_random2 (ap, n);
92       mpn_random2 (bp, n);
93       mpn_random2 (pp-1, n + 2);
94       p_before = pp[-1];
95       p_after = pp[n];
96
97       itch = mpn_mullo_itch (n);
98       ASSERT_ALWAYS (itch <= mpn_mullo_itch (MAX_N));
99       mpn_random2 (scratch-1, itch+2);
100       s_before = scratch[-1];
101       s_after = scratch[itch];
102
103       mpn_mullo_n (pp, ap, bp, n);
104       mpn_mul_n (refp, ap, bp, n);
105       if (pp[-1] != p_before || pp[n] != p_after
106           || scratch[-1] != s_before || scratch[itch] != s_after
107           || mpn_cmp (refp, pp, n) != 0)
108         {
109           printf ("ERROR in test %d, n = %d",
110                   test, (int) n);
111           if (pp[-1] != p_before)
112             {
113               printf ("before pp:"); mpn_dump (pp -1, 1);
114               printf ("keep:   "); mpn_dump (&p_before, 1);
115             }
116           if (pp[n] != p_after)
117             {
118               printf ("after pp:"); mpn_dump (pp + n, 1);
119               printf ("keep:   "); mpn_dump (&p_after, 1);
120             }
121           if (scratch[-1] != s_before)
122             {
123               printf ("before scratch:"); mpn_dump (scratch-1, 1);
124               printf ("keep:   "); mpn_dump (&s_before, 1);
125             }
126           if (scratch[itch] != s_after)
127             {
128               printf ("after scratch:"); mpn_dump (scratch + itch, 1);
129               printf ("keep:   "); mpn_dump (&s_after, 1);
130             }
131           mpn_dump (ap, n);
132           mpn_dump (bp, n);
133           mpn_dump (pp, n);
134           mpn_dump (refp, n);
135
136           abort();
137         }
138     }
139   TMP_FREE;
140   tests_end ();
141   return 0;
142 }