11f40b9543d70f98727aa50f1115b38de742b6c5
[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 https://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
67       n = 1 + gmp_urandomm_ui (rands, MAX_LIMBS);
68
69       if (i & 1)
70         mpn_random2 (ap, n);
71       else
72         mpn_random (ap, n);
73
74       ap[0] |= 1;
75
76       if (i < 100)
77         k = 3 + 2*i;
78       else
79         {
80           mpn_random (&k, 1);
81           if (k < 3)
82             k = 3;
83           else
84             k |= 1;
85         }
86       mpn_brootinv (rp, ap, n, k, scratch);
87       mpn_powlo (pp, rp, &k, 1, n, scratch);
88       mpn_mullo_n (app, ap, pp, n);
89
90       if (app[0] != 1 || !mpn_zero_p (app+1, n-1))
91         {
92           gmp_fprintf (stderr,
93                        "mpn_brootinv returned bad result: %u limbs\n",
94                        (unsigned) n);
95           gmp_fprintf (stderr, "k     = %Mx\n", k);
96           gmp_fprintf (stderr, "a     = %Nx\n", ap, n);
97           gmp_fprintf (stderr, "r     = %Nx\n", rp, n);
98           gmp_fprintf (stderr, "r^n   = %Nx\n", pp, n);
99           gmp_fprintf (stderr, "a r^n = %Nx\n", app, n);
100           abort ();
101         }
102     }
103   TMP_FREE;
104   tests_end ();
105   return 0;
106 }