[BACK]Return to misc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tests

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>