Annotation of OpenXM_contrib/gmp/tests/rand/gen.c, Revision 1.1
1.1 ! maekawa 1: /* gen.c -- Generate pseudorandom numbers. */
! 2:
! 3: /*
! 4: Copyright (C) 1999, 2000 Free Software Foundation, Inc.
! 5:
! 6: This file is part of the GNU MP Library.
! 7:
! 8: The GNU MP Library is free software; you can redistribute it and/or modify
! 9: it under the terms of the GNU Lesser General Public License as published by
! 10: the Free Software Foundation; either version 2.1 of the License, or (at your
! 11: option) any later version.
! 12:
! 13: The GNU MP Library is distributed in the hope that it will be useful, but
! 14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 15: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 16: License for more details.
! 17:
! 18: You should have received a copy of the GNU Lesser General Public License
! 19: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 21: MA 02111-1307, USA.
! 22: */
! 23:
! 24: /* Examples:
! 25:
! 26: $ gen 10
! 27: 10 integers 0 <= X < 2^32 generated by mpz_urandomb()
! 28:
! 29: $ gen -f mpf_urandomb 10
! 30: 10 real numbers 0 <= X < 1
! 31:
! 32: $ gen -z 127 10
! 33: 10 integers 0 <= X < 2^127
! 34:
! 35: $ gen -f mpf_urandomb -x .9,1 10
! 36: 10 real numbers 0 <= X < .9
! 37:
! 38: $ gen -s 1 10
! 39: 10 integers, sequence seeded with 1
! 40:
! 41: */
! 42:
! 43: #include <stdio.h>
! 44: #include <stdlib.h>
! 45: #include <unistd.h>
! 46: #include <limits.h>
! 47: #include <errno.h>
! 48: #include <time.h>
! 49: #include <string.h>
! 50:
! 51: #if !HAVE_DECL_OPTARG
! 52: extern char *optarg;
! 53: extern int optind, opterr;
! 54: #endif
! 55:
! 56: #include "gmp.h"
! 57: #include "gmp-impl.h"
! 58:
! 59: int main (argc, argv)
! 60: int argc;
! 61: char *argv[];
! 62: {
! 63: const char usage[] =
! 64: "usage: gen [-bhpq] [-a n] [-c a,c,m2exp] [-C a,c,m] [-f func] [-g alg] [-m n] [-s n] " \
! 65: "[-x f,t] [-z n] [n]\n" \
! 66: " n number of random numbers to generate\n" \
! 67: " -a n ASCII output in radix n (default, with n=10)\n" \
! 68: " -b binary output\n" \
! 69: " -c a,c,m2exp use supplied LC scheme\n" \
! 70: " -C a,c,m use supplied LC scheme\n" \
! 71: " -f func random function, one of\n" \
! 72: " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \
! 73: " -g alg algorithm, one of lc (default), bbs\n" \
! 74: " -h print this text and exit\n" \
! 75: " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \
! 76: " -p print used seed on stderr\n" \
! 77: " -q quiet, no output\n" \
! 78: " -s n initial seed (default: output from time(3))\n" \
! 79: " -x f,t exclude all numbers f <= x <= t\n" \
! 80: " -z n size in bits of generated numbers (0<= X <2^n) (default 32)\n" \
! 81: "";
! 82:
! 83: unsigned long int f;
! 84: unsigned long int n = 0;
! 85: unsigned long int seed;
! 86: unsigned long int m2exp = 0;
! 87: unsigned int size = 32;
! 88: int seed_from_user = 0;
! 89: int ascout = 1, binout = 0, printseed = 0;
! 90: int output_radix = 10;
! 91: int lc_scheme_from_user = 0;
! 92: int quiet_flag = 0;
! 93: mpz_t z_seed;
! 94: mpz_t z1;
! 95: mpf_t f1;
! 96: gmp_randstate_t rstate;
! 97: int c, i;
! 98: double drand;
! 99: long lrand;
! 100: int do_exclude = 0;
! 101: mpf_t f_xf, f_xt; /* numbers to exclude from sequence */
! 102: char *str_xf, *str_xt; /* numbers to exclude from sequence */
! 103: char *str_a, *str_adder, *str_m;
! 104: mpz_t z_a, z_m, z_mmax;
! 105: unsigned long int ul_adder;
! 106:
! 107: enum
! 108: {
! 109: RFUNC_mpz_urandomb = 0,
! 110: RFUNC_mpz_urandomm,
! 111: RFUNC_mpf_urandomb,
! 112: RFUNC_rand,
! 113: RFUNC_random,
! 114: } rfunc = RFUNC_mpz_urandomb;
! 115: char *rfunc_str[] = { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb",
! 116: "rand", "random" };
! 117: gmp_randalg_t ralg = GMP_RAND_ALG_DEFAULT;
! 118: char *ralg_str[] = { "lc", "bbs" };
! 119:
! 120: mpf_init (f_xf);
! 121: mpf_init (f_xt);
! 122: mpf_init (f1);
! 123: mpz_init (z1);
! 124: mpz_init (z_seed);
! 125: mpz_init_set_ui (z_mmax, 0);
! 126:
! 127:
! 128: while ((c = getopt (argc, argv, "a:bc:C:f:g:hm:n:pqs:z:x:")) != -1)
! 129: switch (c)
! 130: {
! 131: case 'a':
! 132: ascout = 1;
! 133: binout = 0;
! 134: output_radix = atoi (optarg);
! 135: break;
! 136:
! 137: case 'b':
! 138: ascout = 0;
! 139: binout = 1;
! 140: break;
! 141:
! 142: case 'c': /* User supplied LC scheme: a,c,m2exp */
! 143: case 'C': /* User supplied LC scheme: a,c,m */
! 144: if (NULL == (str_a = strtok (optarg, ","))
! 145: || NULL == (str_adder = strtok (NULL, ","))
! 146: || NULL == (str_m = strtok (NULL, ",")))
! 147: {
! 148: fprintf (stderr, "gen: bad LC scheme parameters: %s\n", optarg);
! 149: exit (1);
! 150: }
! 151: #ifdef HAVE_STRTOUL
! 152: ul_adder = strtoul (str_adder, NULL, 0);
! 153: #elif HAVE_STRTOL
! 154: ul_adder = (unsigned long int) strtol (str_adder, NULL, 0);
! 155: #else
! 156: ul_adder = (unsigned long int) atoi (str_adder);
! 157: #endif
! 158:
! 159: if (mpz_init_set_str (z_a, str_a, 0))
! 160: {
! 161: fprintf (stderr, "gen: bad LC scheme parameter `a': %s\n", str_a);
! 162: exit (1);
! 163: }
! 164: if (ULONG_MAX == ul_adder)
! 165: {
! 166: fprintf (stderr, "gen: bad LC scheme parameter `c': %s\n",
! 167: str_adder);
! 168: exit (1);
! 169: }
! 170: if (c == 'c')
! 171: m2exp = atol (str_m);
! 172: else
! 173: mpz_init_set_str (z_m, str_m, 0);
! 174:
! 175: lc_scheme_from_user = 1;
! 176: break;
! 177:
! 178:
! 179: case 'f':
! 180: rfunc = -1;
! 181: for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++)
! 182: if (!strcmp (optarg, rfunc_str[f]))
! 183: {
! 184: rfunc = f;
! 185: break;
! 186: }
! 187: if (rfunc == -1)
! 188: {
! 189: fputs (usage, stderr);
! 190: exit (1);
! 191: }
! 192: break;
! 193:
! 194: case 'g': /* algorithm */
! 195: ralg = -1;
! 196: for (f = 0; f < sizeof (ralg_str) / sizeof (*ralg_str); f++)
! 197: if (!strcmp (optarg, ralg_str[f]))
! 198: {
! 199: ralg = f;
! 200: break;
! 201: }
! 202: if (ralg == -1)
! 203: {
! 204: fputs (usage, stderr);
! 205: exit (1);
! 206: }
! 207: break;
! 208:
! 209: case 'm': /* max for mpz_urandomm() */
! 210: if (mpz_set_str (z_mmax, optarg, 0))
! 211: {
! 212: fprintf (stderr, "gen: bad max value: %s\n", optarg);
! 213: exit (1);
! 214: }
! 215: break;
! 216:
! 217: case 'p': /* print seed on stderr */
! 218: printseed = 1;
! 219: break;
! 220:
! 221: case 'q': /* quiet */
! 222: quiet_flag = 1;
! 223: break;
! 224:
! 225: case 's': /* user provided seed */
! 226: if (mpz_set_str (z_seed, optarg, 0))
! 227: {
! 228: fprintf (stderr, "gen: bad seed argument %s\n", optarg);
! 229: exit (1);
! 230: }
! 231: seed_from_user = 1;
! 232: break;
! 233:
! 234: case 'z':
! 235: size = atoi (optarg);
! 236: if (size < 1)
! 237: {
! 238: fprintf (stderr, "gen: bad size argument (-z %u)\n", size);
! 239: exit (1);
! 240: }
! 241: break;
! 242:
! 243: case 'x': /* Exclude. from,to */
! 244: str_xf = optarg;
! 245: str_xt = strchr (optarg, ',');
! 246: if (NULL == str_xt)
! 247: {
! 248: fprintf (stderr, "gen: bad exclusion parameters: %s\n", optarg);
! 249: exit (1);
! 250: }
! 251: *str_xt++ = '\0';
! 252: do_exclude = 1;
! 253: break;
! 254:
! 255: case 'h':
! 256: case '?':
! 257: default:
! 258: fputs (usage, stderr);
! 259: exit (1);
! 260: }
! 261: argc -= optind;
! 262: argv += optind;
! 263:
! 264: if (! seed_from_user)
! 265: mpz_set_ui (z_seed, (unsigned long int) time (NULL));
! 266: seed = mpz_get_ui (z_seed);
! 267: if (printseed)
! 268: {
! 269: fprintf (stderr, "gen: seed used: ");
! 270: mpz_out_str (stderr, output_radix, z_seed);
! 271: fprintf (stderr, "\n");
! 272: }
! 273:
! 274: mpf_set_prec (f1, size);
! 275:
! 276: /* init random state and plant seed */
! 277: switch (rfunc)
! 278: {
! 279: case RFUNC_mpf_urandomb:
! 280: #if 0
! 281: /* Don't init a too small generator. */
! 282: size = PREC (f1) * BITS_PER_MP_LIMB;
! 283: /* Fall through. */
! 284: #endif
! 285: case RFUNC_mpz_urandomb:
! 286: case RFUNC_mpz_urandomm:
! 287: if (! lc_scheme_from_user)
! 288: {
! 289: gmp_randinit (rstate, ralg, MIN (128, size));
! 290: }
! 291: else
! 292: {
! 293: if (m2exp != 0)
! 294: gmp_randinit_lc_2exp (rstate, z_a, ul_adder, m2exp);
! 295: else
! 296: gmp_randinit_lc (rstate, z_a, ul_adder, z_m);
! 297: }
! 298:
! 299: if (gmp_errno != GMP_ERROR_NONE)
! 300: {
! 301: if (gmp_errno & GMP_ERROR_INVALID_ARGUMENT)
! 302: fprintf (stderr, "gen: asking for too big random state\n");
! 303: if (gmp_errno & GMP_ERROR_UNSUPPORTED_ARGUMENT)
! 304: fprintf (stderr, "gen: unsupported algorithm\n");
! 305: exit (1);
! 306: }
! 307: gmp_randseed (rstate, z_seed);
! 308: break;
! 309:
! 310: case RFUNC_rand:
! 311: srand (seed);
! 312: break;
! 313:
! 314: case RFUNC_random:
! 315: #ifdef __FreeBSD__ /* FIXME */
! 316: if (seed_from_user)
! 317: srandom (seed);
! 318: else
! 319: srandomdev ();
! 320: #else
! 321: fprintf (stderr, "gen: unsupported algorithm\n");
! 322: #endif
! 323: break;
! 324:
! 325: default:
! 326: fprintf (stderr, "gen: random function not implemented\n");
! 327: exit (1);
! 328: }
! 329:
! 330: /* set up excludes */
! 331: if (do_exclude)
! 332: switch (rfunc)
! 333: {
! 334: case RFUNC_mpf_urandomb:
! 335:
! 336: if (mpf_set_str (f_xf, str_xf, 10) ||
! 337: mpf_set_str (f_xt, str_xt, 10))
! 338: {
! 339: fprintf (stderr, "gen: bad exclusion-from (\"%s\") " \
! 340: "or exclusion-to (\"%s\") string. no exclusion done.\n",
! 341: str_xf, str_xt);
! 342: do_exclude = 0;
! 343: }
! 344: break;
! 345:
! 346: default:
! 347: fprintf (stderr, "gen: exclusion not implemented for chosen " \
! 348: "randomization function. all numbers included in sequence.\n");
! 349: }
! 350:
! 351: /* generate and print */
! 352: if (argc > 0)
! 353: {
! 354: #if HAVE_STRTOUL
! 355: n = strtoul (argv[0], (char **) NULL, 10);
! 356: #elif HAVE_STRTOL
! 357: n = (unsigned long int) strtol (argv[0], (char **) NULL, 10);
! 358: #else
! 359: n = (unsigned long int) atoi (argv[0]);
! 360: #endif
! 361: }
! 362:
! 363: for (f = 0; n == 0 || f < n; f++)
! 364: {
! 365: switch (rfunc)
! 366: {
! 367: case RFUNC_mpz_urandomb:
! 368: mpz_urandomb (z1, rstate, size);
! 369: if (quiet_flag)
! 370: break;
! 371: if (binout)
! 372: {
! 373: /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
! 374: fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
! 375: exit (1);
! 376: }
! 377: else
! 378: {
! 379: mpz_out_str (stdout, output_radix, z1);
! 380: puts ("");
! 381: }
! 382: break;
! 383:
! 384: case RFUNC_mpz_urandomm:
! 385: mpz_urandomm (z1, rstate, z_mmax);
! 386: if (quiet_flag)
! 387: break;
! 388: if (binout)
! 389: {
! 390: /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
! 391: fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
! 392: exit (1);
! 393: }
! 394: else
! 395: {
! 396: mpz_out_str (stdout, output_radix, z1);
! 397: puts ("");
! 398: }
! 399: break;
! 400:
! 401: case RFUNC_mpf_urandomb:
! 402: mpf_urandomb (f1, rstate, size);
! 403: if (do_exclude)
! 404: if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0)
! 405: break;
! 406: if (quiet_flag)
! 407: break;
! 408: if (binout)
! 409: {
! 410: fprintf (stderr, "gen: binary output for floating point numbers "\
! 411: "not implemented\n");
! 412: exit (1);
! 413: }
! 414: else
! 415: {
! 416: mpf_out_str (stdout, output_radix, 0, f1);
! 417: puts ("");
! 418: }
! 419: break;
! 420:
! 421: case RFUNC_rand:
! 422: i = rand ();
! 423: #ifdef FLOAT_OUTPUT
! 424: if (i)
! 425: drand = (double) i / (double) RAND_MAX;
! 426: else
! 427: drand = 0.0;
! 428: if (quiet_flag)
! 429: break;
! 430: if (binout)
! 431: fwrite (&drand, sizeof (drand), 1, stdout);
! 432: else
! 433: printf ("%e\n", drand);
! 434: #else
! 435: if (quiet_flag)
! 436: break;
! 437: if (binout)
! 438: fwrite (&i, sizeof (i), 1, stdout);
! 439: else
! 440: printf ("%d\n", i);
! 441: #endif
! 442: break;
! 443:
! 444: case RFUNC_random:
! 445: lrand = random ();
! 446: if (lrand)
! 447: drand = (double) lrand / (double) 0x7fffffff;
! 448: else
! 449: drand = 0;
! 450: if (quiet_flag)
! 451: break;
! 452: if (binout)
! 453: fwrite (&drand, sizeof (drand), 1, stdout);
! 454: else
! 455: printf ("%e\n", drand);
! 456: break;
! 457:
! 458: default:
! 459: fprintf (stderr, "gen: random function not implemented\n");
! 460: exit (1);
! 461: }
! 462:
! 463: }
! 464:
! 465: /* clean up */
! 466: switch (rfunc)
! 467: {
! 468: case RFUNC_mpz_urandomb:
! 469: case RFUNC_mpf_urandomb:
! 470: gmp_randclear (rstate);
! 471: break;
! 472: default:
! 473: break;
! 474: }
! 475: mpf_clear (f1);
! 476: mpf_clear (f_xf);
! 477: mpf_clear (f_xt);
! 478: mpz_clear (z1);
! 479: mpz_clear (z_seed);
! 480:
! 481: return 0;
! 482: }
! 483:
! 484: static void *debug_dummyz = mpz_dump;
! 485: static void *debug_dummyf = mpf_dump;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>