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

Revision 18191, 4.8 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_pow_ui and mpz_ui_pow_ui.
2
3Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 02111-1307, USA.
21*/
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "gmp.h"
27#include "gmp-impl.h"
28#include "tests.h"
29
30
31void
32check_one (mpz_srcptr want, mpz_srcptr base, unsigned long exp)
33{
34  mpz_t  got;
35
36  mpz_init (got);
37
38  mpz_pow_ui (got, base, exp);
39  if (mpz_cmp (got, want))
40    {
41      printf ("mpz_pow_ui wrong\n");
42      mpz_trace ("  base", base);
43      printf    ("  exp = %lu (0x%lX)\n", exp, exp);
44      mpz_trace ("  got ", got);
45      mpz_trace ("  want", want);
46      abort ();
47    }
48
49  mpz_set (got, base);
50  mpz_pow_ui (got, got, exp);
51  if (mpz_cmp (got, want))
52    {
53      printf ("mpz_pow_ui wrong\n");
54      mpz_trace ("  base", base);
55      printf    ("  exp = %lu (0x%lX)\n", exp, exp);
56      mpz_trace ("  got ", got);
57      mpz_trace ("  want", want);
58      abort ();
59    }
60
61  if (mpz_fits_ulong_p (base))
62    {
63      unsigned long  base_u = mpz_get_ui (base);
64      mpz_ui_pow_ui (got, base_u, exp);
65      if (mpz_cmp (got, want))
66        {
67          printf    ("mpz_ui_pow_ui wrong\n");
68          printf    ("  base=%lu (0x%lX)\n", base_u, base_u);
69          printf    ("  exp = %lu (0x%lX)\n", exp, exp);
70          mpz_trace ("  got ", got);
71          mpz_trace ("  want", want);
72          abort ();
73        }
74    }
75
76  mpz_clear (got);
77}
78
79void
80check_base (mpz_srcptr base)
81{
82  unsigned long  exp;
83  mpz_t          want;
84
85  mpz_init (want);
86  mpz_set_ui (want, 1L);
87
88  for (exp = 0; exp < 20; exp++)
89    {
90      check_one (want, base, exp);
91      mpz_mul (want, want, base);
92    }
93
94  mpz_clear (want);
95}
96
97void
98check_various (void)
99{
100  static const struct {
101    const char *base;
102  } data[] = {
103    { "0" },
104    { "1" },
105    { "2" },
106    { "3" },
107    { "4" },
108    { "5" },
109    { "6" },
110    { "10" },
111    { "15" },
112    { "16" },
113
114    { "0x1F" },
115    { "0xFF" },
116    { "0x1001" },
117    { "0xFFFF" },
118    { "0x10000001" },
119    { "0x1000000000000001" },
120
121    /* actual size closest to estimate */
122    { "0xFFFFFFFF" },
123    { "0xFFFFFFFFFFFFFFFF" },
124
125    /* same after rshift */
126    { "0xFFFFFFFF0" },
127    { "0xFFFFFFFF00" },
128    { "0xFFFFFFFFFFFFFFFF0" },
129    { "0xFFFFFFFFFFFFFFFF00" },
130
131    /* change from 2 limbs to 1 after rshift */
132    { "0x180000000" },
133    { "0x18000000000000000" },
134
135    /* change from 3 limbs to 2 after rshift */
136    { "0x18000000100000000" },
137    { "0x180000000000000010000000000000000" },
138
139    /* handling of absolute value */
140    { "-0x80000000" },
141    { "-0x8000000000000000" },
142
143    /* low zero limb, and size>2, checking argument overlap detection */
144    { "0x3000000000000000300000000000000030000000000000000" },
145  };
146
147  mpz_t  base;
148  int    i;
149
150  mpz_init (base);
151
152  for (i = 0; i < numberof (data); i++)
153    {
154      mpz_set_str_or_abort (base, data[i].base, 0);
155      check_base (base);
156    }
157
158  mpz_clear (base);
159}
160
161void
162check_random (int reps)
163{
164  mpz_t              base, want;
165  mp_size_t          base_size;
166  int                i;
167  unsigned long      size_range, exp;
168  gmp_randstate_ptr  rands = RANDS;
169 
170  mpz_init (base);
171  mpz_init (want);
172
173  for (i = 0; i < reps; i++)
174    {
175      /* exponentially random 0 to 2^13 bits for base */
176      mpz_urandomb (want, rands, 32);
177      size_range = mpz_get_ui (want) % 12 + 2;
178      mpz_urandomb (want, rands, size_range);
179      base_size = mpz_get_ui (want);
180      mpz_rrandomb (base, rands, base_size);
181
182      /* randomly signed base */
183      mpz_urandomb (want, rands, 2);
184      if ((mpz_get_ui (want) & 1) != 0)
185        mpz_neg (base, base);
186
187      /* random 5 bits for exponent */
188      mpz_urandomb (want, rands, 5L);
189      exp = mpz_get_ui (want);
190
191      refmpz_pow_ui (want, base, exp);
192      check_one (want, base, exp);
193    }
194
195  mpz_clear (base);
196  mpz_clear (want);
197}
198
199int
200main (int argc, char **argv)
201{
202  int reps = 500;
203
204  /* dummy call to drag in refmpn.o for testing mpz/n_pow_ui.c with
205     refmpn_mul_2 */
206  refmpn_zero_p (NULL, (mp_size_t) 0);
207
208  tests_start ();
209  mp_trace_base = -16;
210
211  if (argc == 2)
212     reps = atoi (argv[1]);
213
214  check_various ();
215  check_random (reps);
216
217  tests_end ();
218  exit (0);
219}
Note: See TracBrowser for help on using the repository browser.