source: trunk/third/gmp/tests/mpz/t-powm_ui.c @ 18191

Revision 18191, 3.7 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18190, which included commits to RCS files with non-trunk default branches.
Line 
1/* Test mpz_powm_ui, mpz_mul. mpz_mod.
2
3Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2002 Free Software
4Foundation, Inc.
5
6This file is part of the GNU MP Library.
7
8The GNU MP Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 2.1 of the License, or (at your
11option) any later version.
12
13The GNU MP Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
20the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21MA 02111-1307, USA. */
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "gmp.h"
27#include "gmp-impl.h"
28#include "tests.h"
29
30void dump_abort _PROTO ((mpz_t, mpz_t));
31void debug_mp _PROTO ((mpz_t, int));
32
33int
34main (int argc, char **argv)
35{
36  mpz_t base, exp, mod;
37  mpz_t r1, r2, base2;
38  mp_size_t base_size, exp_size, mod_size;
39  unsigned long int exp2;
40  int i;
41  int reps = 400;
42  gmp_randstate_ptr rands;
43  mpz_t bs;
44  unsigned long bsi, size_range;
45
46  tests_start ();
47  rands = RANDS;
48
49  mpz_init (bs);
50
51  if (argc == 2)
52     reps = atoi (argv[1]);
53
54  mpz_init (base);
55  mpz_init (exp);
56  mpz_init (mod);
57  mpz_init (r1);
58  mpz_init (r2);
59  mpz_init (base2);
60
61  for (i = 0; i < reps; i++)
62    {
63      mpz_urandomb (bs, rands, 32);
64      size_range = mpz_get_ui (bs) % 13 + 2;
65
66      do  /* Loop until mathematically well-defined.  */
67        {
68          mpz_urandomb (bs, rands, size_range);
69          base_size = mpz_get_ui (bs);
70          mpz_rrandomb (base, rands, base_size);
71
72          mpz_urandomb (bs, rands, 6L);
73          exp_size = mpz_get_ui (bs);
74          mpz_rrandomb (exp, rands, exp_size);
75          exp2 = mpz_getlimbn (exp, 0);
76        }
77      while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0);
78
79      do
80        {
81          mpz_urandomb (bs, rands, size_range);
82          mod_size = mpz_get_ui (bs);
83          mpz_rrandomb (mod, rands, mod_size);
84        }
85      while (mpz_cmp_ui (mod, 0) == 0);
86
87      mpz_urandomb (bs, rands, 2);
88      bsi = mpz_get_ui (bs);
89      if ((bsi & 1) != 0)
90        mpz_neg (base, base);
91
92      /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */
93
94#if 0
95      putc ('\n', stderr);
96      debug_mp (base, -16);
97      debug_mp (mod, -16);
98#endif
99
100      mpz_powm_ui (r1, base, exp2, mod);
101
102      mpz_set_ui (r2, 1);
103      mpz_set (base2, base);
104
105      mpz_mod (r2, r2, mod);    /* needed when exp==0 and mod==1 */
106      while (exp2 != 0)
107        {
108          if (exp2 % 2 != 0)
109            {
110              mpz_mul (r2, r2, base2);
111              mpz_mod (r2, r2, mod);
112            }
113          mpz_mul (base2, base2, base2);
114          mpz_mod (base2, base2, mod);
115          exp2 = exp2 / 2;
116        }
117
118#if 0
119      debug_mp (r1, -16);
120      debug_mp (r2, -16);
121#endif
122
123      if (mpz_cmp (r1, r2) != 0)
124        {
125          fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i);
126          debug_mp (base, -16);
127          debug_mp (exp, -16);
128          debug_mp (mod, -16);
129          fprintf (stderr, "mpz_powm result:\n");
130          debug_mp (r1, -16);
131          fprintf (stderr, "reference result:\n");
132          debug_mp (r2, -16);
133          abort ();
134        }
135    }
136
137  mpz_clear (bs);
138  mpz_clear (base);
139  mpz_clear (exp);
140  mpz_clear (mod);
141  mpz_clear (r1);
142  mpz_clear (r2);
143  mpz_clear (base2);
144
145  tests_end ();
146  exit (0);
147}
148
149void
150dump_abort (mpz_t dividend, mpz_t divisor)
151{
152  fprintf (stderr, "ERROR\n");
153  fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
154  fprintf (stderr, "divisor  = "); debug_mp (divisor, -16);
155  abort();
156}
157
158void
159debug_mp (mpz_t x, int base)
160{
161  mpz_out_str (stderr, base, x); fputc ('\n', stderr);
162}
Note: See TracBrowser for help on using the repository browser.