78b25151e646ca5e7ed049a9047459494c063026
[platform/upstream/gmp.git] / tests / mpn / t-brootinv.c
1 /* Copyright 2012 Free Software Foundation, Inc.
2
3 This file is part of the GNU MP Library test suite.
4
5 The GNU MP Library test suite is free software; you can redistribute it
6 and/or modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 3 of the License,
8 or (at your option) any later version.
9
10 The GNU MP Library test suite is distributed in the hope that it will be
11 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along with
16 the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
17
18
19 #include <stdlib.h>             /* for strtol */
20 #include <stdio.h>              /* for printf */
21
22 #include "gmp.h"
23 #include "gmp-impl.h"
24 #include "longlong.h"
25 #include "tests/tests.h"
26
27 #define MAX_LIMBS 150
28 #define COUNT 500
29
30 int
31 main (int argc, char **argv)
32 {
33   gmp_randstate_ptr rands;
34
35   mp_ptr ap, rp, pp, app, scratch;
36   int count = COUNT;
37   unsigned i;
38   TMP_DECL;
39
40   TMP_MARK;
41
42   if (argc > 1)
43     {
44       char *end;
45       count = strtol (argv[1], &end, 0);
46       if (*end || count <= 0)
47         {
48           fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
49           return 1;
50         }
51     }
52
53   tests_start ();
54   rands = RANDS;
55
56   ap = TMP_ALLOC_LIMBS (MAX_LIMBS);
57   rp = TMP_ALLOC_LIMBS (MAX_LIMBS);
58   pp = TMP_ALLOC_LIMBS (MAX_LIMBS);
59   app = TMP_ALLOC_LIMBS (MAX_LIMBS);
60   scratch = TMP_ALLOC_LIMBS (5*MAX_LIMBS);
61
62   for (i = 0; i < count; i++)
63     {
64       mp_size_t n;
65       mp_limb_t k;
66       int c;
67
68       n = 1 + gmp_urandomm_ui (rands, MAX_LIMBS);
69
70       if (i & 1)
71         mpn_random2 (ap, n);
72       else
73         mpn_random (ap, n);
74
75       ap[0] |= 1;
76
77       if (i < 100)
78         k = 3 + 2*i;
79       else
80         {
81           mpn_random (&k, 1);
82           if (k < 3)
83             k = 3;
84           else
85             k |= 1;
86         }
87       mpn_brootinv (rp, ap, n, k, scratch);
88       mpn_powlo (pp, rp, &k, 1, n, scratch);
89       mpn_mullo_n (app, ap, pp, n);
90
91       if (app[0] != 1 || !mpn_zero_p (app+1, n-1))
92         {
93           gmp_fprintf (stderr,
94                        "mpn_brootinv returned bad result: %u limbs\n",
95                        (unsigned) n);
96           gmp_fprintf (stderr, "k     = %Mx\n", k);
97           gmp_fprintf (stderr, "a     = %Nx\n", ap, n);
98           gmp_fprintf (stderr, "r     = %Nx\n", rp, n);
99           gmp_fprintf (stderr, "r^n   = %Nx\n", pp, n);
100           gmp_fprintf (stderr, "a r^n = %Nx\n", app, n);
101           abort ();
102         }
103     }
104   TMP_FREE;
105   tests_end ();
106   return 0;
107 }