Annotation of OpenXM_contrib/gmp/tests/misc.c, Revision 1.1.1.1
1.1 ohara 1: /* Miscellaneous test program support routines.
2:
3: Copyright 2000, 2001, 2002 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 2.1 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; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include "config.h"
23:
24: #include <ctype.h>
25: #include <stdio.h>
26: #include <stdlib.h> /* for getenv */
27: #include <string.h>
28:
29: #if TIME_WITH_SYS_TIME
30: # include <sys/time.h> /* for struct timeval */
31: # include <time.h>
32: #else
33: # if HAVE_SYS_TIME_H
34: # include <sys/time.h>
35: # else
36: # include <time.h>
37: # endif
38: #endif
39:
40: #include "gmp.h"
41: #include "gmp-impl.h"
42: #include "tests.h"
43:
44:
45: /* The various tests setups and final checks, collected up together. */
46: void
47: tests_start (void)
48: {
49: tests_memory_start ();
50: tests_rand_start ();
51: }
52: void
53: tests_end (void)
54: {
55: tests_rand_end ();
56: tests_memory_end ();
57: }
58:
59:
60: void
61: tests_rand_start (void)
62: {
63: gmp_randstate_ptr rands;
64: char *perform_seed;
65: unsigned long seed;
66:
67: if (__gmp_rands_initialized)
68: {
69: printf ("Please let tests_start() initialize the global __gmp_rands.\n");
70: printf ("ie. ensure that function is called before the first use of RANDS.\n");
71: abort ();
72: }
73: rands = RANDS;
74:
75: perform_seed = getenv ("GMP_CHECK_RANDOMIZE");
76: if (perform_seed != NULL)
77: {
78: seed = atoi (perform_seed);
79: if (! (seed == 0 || seed == 1))
80: {
81: printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
82: gmp_randseed_ui (rands, seed);
83: }
84: else
85: {
86: #if HAVE_GETTIMEOFDAY
87: struct timeval tv;
88: gettimeofday (&tv, NULL);
89: seed = tv.tv_sec + tv.tv_usec;
90: #else
91: time_t tv;
92: time (&tv);
93: seed = tv;
94: #endif
95: gmp_randseed_ui (rands, seed);
96: printf ("Seed GMP_CHECK_RANDOMIZE=%lu (include this in bug reports)\n", seed);
97: }
98: }
99: }
100: void
101: tests_rand_end (void)
102: {
103: RANDS_CLEAR ();
104: }
105:
106:
107: /* Only used if CPU calling conventions checking is available. */
108: mp_limb_t (*calling_conventions_function) _PROTO ((ANYARGS));
109:
110:
111: /* Return p advanced to the next multiple of "align" bytes. "align" must be
112: a power of 2. Care is taken not to assume sizeof(int)==sizeof(pointer).
113: Using "unsigned long" avoids a warning on hpux. */
114: void *
115: align_pointer (void *p, size_t align)
116: {
117: unsigned long d;
118: d = ((unsigned long) p) & (align-1);
119: d = (d != 0 ? align-d : 0);
120: return (void *) (((char *) p) + d);
121: }
122:
123:
124: /* Note that memory allocated with this function can never be freed, because
125: the start address of the block allocated is lost. */
126: void *
127: __gmp_allocate_func_aligned (size_t bytes, size_t align)
128: {
129: return align_pointer ((*__gmp_allocate_func) (bytes + align-1), align);
130: }
131:
132:
133: void *
134: __gmp_allocate_or_reallocate (void *ptr, size_t oldsize, size_t newsize)
135: {
136: if (ptr == NULL)
137: return (*__gmp_allocate_func) (newsize);
138: else
139: return (*__gmp_reallocate_func) (ptr, oldsize, newsize);
140: }
141:
142: char *
143: __gmp_allocate_strdup (const char *s)
144: {
145: size_t len;
146: char *t;
147: len = strlen (s);
148: t = (*__gmp_allocate_func) (len+1);
149: memcpy (t, s, len+1);
150: return t;
151: }
152:
153:
154: char *
155: strtoupper (char *s_orig)
156: {
157: char *s;
158: for (s = s_orig; *s != '\0'; s++)
159: if (isascii (*s))
160: *s = toupper (*s);
161: return s_orig;
162: }
163:
164:
165: void
166: mpz_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size)
167: {
168: ASSERT (size >= 0);
169: MPN_NORMALIZE (p, size);
170: MPZ_REALLOC (z, size);
171: MPN_COPY (PTR(z), p, size);
172: SIZ(z) = size;
173: }
174:
175: void
176: mpz_init_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size)
177: {
178: ASSERT (size >= 0);
179:
180: MPN_NORMALIZE (p, size);
181: ALLOC(z) = MAX (size, 1);
182: PTR(z) = __GMP_ALLOCATE_FUNC_LIMBS (ALLOC(z));
183: SIZ(z) = size;
184: MPN_COPY (PTR(z), p, size);
185: }
186:
187:
188: /* Find least significant limb position where p1,size and p2,size differ. */
189: mp_size_t
190: mpn_diff_lowest (mp_srcptr p1, mp_srcptr p2, mp_size_t size)
191: {
192: mp_size_t i;
193:
194: for (i = 0; i < size; i++)
195: if (p1[i] != p2[i])
196: return i;
197:
198: /* no differences */
199: return -1;
200: }
201:
202:
203: /* Find most significant limb position where p1,size and p2,size differ. */
204: mp_size_t
205: mpn_diff_highest (mp_srcptr p1, mp_srcptr p2, mp_size_t size)
206: {
207: mp_size_t i;
208:
209: for (i = size-1; i >= 0; i--)
210: if (p1[i] != p2[i])
211: return i;
212:
213: /* no differences */
214: return -1;
215: }
216:
217:
218: /* Find least significant byte position where p1,size and p2,size differ. */
219: mp_size_t
220: byte_diff_lowest (const void *p1, const void *p2, mp_size_t size)
221: {
222: mp_size_t i;
223:
224: for (i = 0; i < size; i++)
225: if (((const char *) p1)[i] != ((const char *) p2)[i])
226: return i;
227:
228: /* no differences */
229: return -1;
230: }
231:
232:
233: /* Find most significant limb position where p1,size and p2,size differ. */
234: mp_size_t
235: byte_diff_highest (const void *p1, const void *p2, mp_size_t size)
236: {
237: mp_size_t i;
238:
239: for (i = size-1; i >= 0; i--)
240: if (((const char *) p1)[i] != ((const char *) p2)[i])
241: return i;
242:
243: /* no differences */
244: return -1;
245: }
246:
247:
248: void
249: mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
250: {
251: if (mpz_set_str (z, str, base) != 0)
252: {
253: fprintf (stderr, "ERROR: mpz_set_str failed\n");
254: fprintf (stderr, " str = \"%s\"\n", str);
255: fprintf (stderr, " base = %d\n", base);
256: abort();
257: }
258: }
259:
260: void
261: mpq_set_str_or_abort (mpq_ptr q, const char *str, int base)
262: {
263: if (mpq_set_str (q, str, base) != 0)
264: {
265: fprintf (stderr, "ERROR: mpq_set_str failed\n");
266: fprintf (stderr, " str = \"%s\"\n", str);
267: fprintf (stderr, " base = %d\n", base);
268: abort();
269: }
270: }
271:
272: void
273: mpf_set_str_or_abort (mpf_ptr f, const char *str, int base)
274: {
275: if (mpf_set_str (f, str, base) != 0)
276: {
277: fprintf (stderr, "ERROR mpf_set_str failed\n");
278: fprintf (stderr, " str = \"%s\"\n", str);
279: fprintf (stderr, " base = %d\n", base);
280: abort();
281: }
282: }
283:
284:
285: /* Whether the absolute value of z is a power of 2. */
286: int
287: mpz_pow2abs_p (mpz_srcptr z)
288: {
289: mp_size_t size, i;
290: mp_srcptr ptr;
291:
292: size = SIZ (z);
293: if (size == 0)
294: return 0; /* zero is not a power of 2 */
295: size = ABS (size);
296:
297: ptr = PTR (z);
298: for (i = 0; i < size-1; i++)
299: if (ptr[i] != 0)
300: return 0; /* non-zero low limb means not a power of 2 */
301:
302: return POW2_P (ptr[i]); /* high limb power of 2 */
303: }
304:
305: void
306: mpz_flipbit (mpz_ptr r, unsigned long bit)
307: {
308: if (mpz_tstbit (r, bit))
309: mpz_clrbit (r, bit);
310: else
311: mpz_setbit (r, bit);
312: }
313:
314:
315: /* Exponentially distributed between 0 and 2^nbits-1, meaning the number of
316: bits in the result is uniformly distributed between 0 and nbits-1.
317:
318: FIXME: This is not a proper exponential distribution, since the
319: probability function will have a stepped shape due to using a uniform
320: distribution after choosing how many bits. */
321:
322: void
323: mpz_erandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
324: {
325: mpz_urandomb (rop, rstate, urandom () % nbits);
326: }
327:
328: void
329: mpz_erandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
330: {
331: mpz_erandomb (rop, rstate, nbits);
332: if (mpz_sgn (rop) == 0)
333: mpz_set_ui (rop, 1L);
334: }
335:
336: void
337: mpz_errandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
338: {
339: mpz_rrandomb (rop, rstate, urandom () % nbits);
340: }
341:
342: void
343: mpz_errandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
344: {
345: mpz_errandomb (rop, rstate, nbits);
346: if (mpz_sgn (rop) == 0)
347: mpz_set_ui (rop, 1L);
348: }
349:
350: void
351: mpz_negrandom (mpz_ptr rop, gmp_randstate_t rstate)
352: {
353: mp_limb_t n;
354: _gmp_rand (&n, rstate, 1);
355: if (n != 0)
356: mpz_neg (rop, rop);
357: }
358:
359: mp_limb_t
360: urandom (void)
361: {
362: #if GMP_NAIL_BITS == 0
363: mp_limb_t n;
364: _gmp_rand (&n, RANDS, BITS_PER_MP_LIMB);
365: return n;
366: #else
367: mp_limb_t n[2];
368: _gmp_rand (n, RANDS, BITS_PER_MP_LIMB);
369: return n[0] + (n[1] << GMP_NUMB_BITS);
370: #endif
371: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>