gen.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:10k
- /* gen.c -- Generate pseudorandom numbers.
- Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
- This file is part of the GNU MP Library.
- The GNU MP Library is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 3 of the License, or (at your
- option) any later version.
- The GNU MP Library is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
- /* Examples:
- $ gen 10
- 10 integers 0 <= X < 2^32 generated by mpz_urandomb()
- $ gen -f mpf_urandomb 10
- 10 real numbers 0 <= X < 1
- $ gen -z 127 10
- 10 integers 0 <= X < 2^127
- $ gen -f mpf_urandomb -x .9,1 10
- 10 real numbers 0 <= X < .9
- $ gen -s 1 10
- 10 integers, sequence seeded with 1
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <limits.h>
- #include <errno.h>
- #include <time.h>
- #include <string.h>
- #if !HAVE_DECL_OPTARG
- extern char *optarg;
- extern int optind, opterr;
- #endif
- #include "gmp.h"
- #include "gmp-impl.h"
- int main (argc, argv)
- int argc;
- char *argv[];
- {
- const char usage[] =
- "usage: gen [-bhpq] [-a n] [-c a,c,m2exp] [-C a,c,m] [-f func] [-g alg] [-m n] [-s n] "
- "[-x f,t] [-z n] [n]n"
- " n number of random numbers to generaten"
- " -a n ASCII output in radix n (default, with n=10)n"
- " -b binary outputn"
- " -c a,c,m2exp use supplied LC schemen"
- " -f func random function, one ofn"
- " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, randomn"
- " -g alg algorithm, one of mt (default), lcn"
- " -h print this text and exitn"
- " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandommn"
- " -p print used seed on stderrn"
- " -q quiet, no outputn"
- " -s n initial seed (default: output from time(3))n"
- " -x f,t exclude all numbers f <= x <= tn"
- " -z n size in bits of generated numbers (0<= X <2^n) (default 32)n"
- "";
- unsigned long int f;
- unsigned long int n = 0;
- unsigned long int seed;
- unsigned long int m2exp = 0;
- unsigned int size = 32;
- int seed_from_user = 0;
- int ascout = 1, binout = 0, printseed = 0;
- int output_radix = 10;
- int lc_scheme_from_user = 0;
- int quiet_flag = 0;
- mpz_t z_seed;
- mpz_t z1;
- mpf_t f1;
- gmp_randstate_t rstate;
- int c, i;
- double drand;
- long lrand;
- int do_exclude = 0;
- mpf_t f_xf, f_xt; /* numbers to exclude from sequence */
- char *str_xf, *str_xt; /* numbers to exclude from sequence */
- char *str_a, *str_adder, *str_m;
- mpz_t z_a, z_m, z_mmax;
- unsigned long int ul_adder;
- enum
- {
- RFUNC_mpz_urandomb = 0,
- RFUNC_mpz_urandomm,
- RFUNC_mpf_urandomb,
- RFUNC_rand,
- RFUNC_random,
- } rfunc = RFUNC_mpz_urandomb;
- char *rfunc_str[] = { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb",
- "rand", "random" };
- enum
- {
- RNG_MT = 0,
- RNG_LC
- };
- gmp_randalg_t ralg = RNG_MT;
- /* Texts for the algorithms. The index of each must match the
- corresponding algorithm in the enum above. */
- char *ralg_str[] = { "mt", "lc" };
- mpf_init (f_xf);
- mpf_init (f_xt);
- mpf_init (f1);
- mpz_init (z1);
- mpz_init (z_seed);
- mpz_init_set_ui (z_mmax, 0);
- while ((c = getopt (argc, argv, "a:bc:f:g:hm:n:pqs:z:x:")) != -1)
- switch (c)
- {
- case 'a':
- ascout = 1;
- binout = 0;
- output_radix = atoi (optarg);
- break;
- case 'b':
- ascout = 0;
- binout = 1;
- break;
- case 'c': /* User supplied LC scheme: a,c,m2exp */
- if (NULL == (str_a = strtok (optarg, ","))
- || NULL == (str_adder = strtok (NULL, ","))
- || NULL == (str_m = strtok (NULL, ",")))
- {
- fprintf (stderr, "gen: bad LC scheme parameters: %sn", optarg);
- exit (1);
- }
- #ifdef HAVE_STRTOUL
- ul_adder = strtoul (str_adder, NULL, 0);
- #elif HAVE_STRTOL
- ul_adder = (unsigned long int) strtol (str_adder, NULL, 0);
- #else
- ul_adder = (unsigned long int) atoi (str_adder);
- #endif
- if (mpz_init_set_str (z_a, str_a, 0))
- {
- fprintf (stderr, "gen: bad LC scheme parameter `a': %sn", str_a);
- exit (1);
- }
- if (ULONG_MAX == ul_adder)
- {
- fprintf (stderr, "gen: bad LC scheme parameter `c': %sn",
- str_adder);
- exit (1);
- }
- m2exp = atol (str_m);
- lc_scheme_from_user = 1;
- break;
- case 'f':
- rfunc = -1;
- for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++)
- if (!strcmp (optarg, rfunc_str[f]))
- {
- rfunc = f;
- break;
- }
- if (rfunc == -1)
- {
- fputs (usage, stderr);
- exit (1);
- }
- break;
- case 'g': /* algorithm */
- ralg = -1;
- for (f = 0; f < sizeof (ralg_str) / sizeof (*ralg_str); f++)
- if (!strcmp (optarg, ralg_str[f]))
- {
- ralg = f;
- break;
- }
- if (ralg == -1)
- {
- fputs (usage, stderr);
- exit (1);
- }
- break;
- case 'm': /* max for mpz_urandomm() */
- if (mpz_set_str (z_mmax, optarg, 0))
- {
- fprintf (stderr, "gen: bad max value: %sn", optarg);
- exit (1);
- }
- break;
- case 'p': /* print seed on stderr */
- printseed = 1;
- break;
- case 'q': /* quiet */
- quiet_flag = 1;
- break;
- case 's': /* user provided seed */
- if (mpz_set_str (z_seed, optarg, 0))
- {
- fprintf (stderr, "gen: bad seed argument %sn", optarg);
- exit (1);
- }
- seed_from_user = 1;
- break;
- case 'z':
- size = atoi (optarg);
- if (size < 1)
- {
- fprintf (stderr, "gen: bad size argument (-z %u)n", size);
- exit (1);
- }
- break;
- case 'x': /* Exclude. from,to */
- str_xf = optarg;
- str_xt = strchr (optarg, ',');
- if (NULL == str_xt)
- {
- fprintf (stderr, "gen: bad exclusion parameters: %sn", optarg);
- exit (1);
- }
- *str_xt++ = ' ';
- do_exclude = 1;
- break;
- case 'h':
- case '?':
- default:
- fputs (usage, stderr);
- exit (1);
- }
- argc -= optind;
- argv += optind;
- if (! seed_from_user)
- mpz_set_ui (z_seed, (unsigned long int) time (NULL));
- seed = mpz_get_ui (z_seed);
- if (printseed)
- {
- fprintf (stderr, "gen: seed used: ");
- mpz_out_str (stderr, output_radix, z_seed);
- fprintf (stderr, "n");
- }
- mpf_set_prec (f1, size);
- /* init random state and plant seed */
- switch (rfunc)
- {
- case RFUNC_mpf_urandomb:
- #if 0
- /* Don't init a too small generator. */
- size = PREC (f1) * GMP_LIMB_BITS;
- /* Fall through. */
- #endif
- case RFUNC_mpz_urandomb:
- case RFUNC_mpz_urandomm:
- switch (ralg)
- {
- case RNG_MT:
- gmp_randinit_mt (rstate);
- break;
- case RNG_LC:
- if (! lc_scheme_from_user)
- gmp_randinit_lc_2exp_size (rstate, MIN (128, size));
- else
- gmp_randinit_lc_2exp (rstate, z_a, ul_adder, m2exp);
- break;
- default:
- fprintf (stderr, "gen: unsupported algorithmn");
- exit (1);
- }
- gmp_randseed (rstate, z_seed);
- break;
- case RFUNC_rand:
- srand (seed);
- break;
- case RFUNC_random:
- #ifdef __FreeBSD__ /* FIXME */
- if (seed_from_user)
- srandom (seed);
- else
- srandomdev ();
- #else
- fprintf (stderr, "gen: unsupported algorithmn");
- #endif
- break;
- default:
- fprintf (stderr, "gen: random function not implementedn");
- exit (1);
- }
- /* set up excludes */
- if (do_exclude)
- switch (rfunc)
- {
- case RFUNC_mpf_urandomb:
- if (mpf_set_str (f_xf, str_xf, 10) ||
- mpf_set_str (f_xt, str_xt, 10))
- {
- fprintf (stderr, "gen: bad exclusion-from ("%s") "
- "or exclusion-to ("%s") string. no exclusion done.n",
- str_xf, str_xt);
- do_exclude = 0;
- }
- break;
- default:
- fprintf (stderr, "gen: exclusion not implemented for chosen "
- "randomization function. all numbers included in sequence.n");
- }
- /* generate and print */
- if (argc > 0)
- {
- #if HAVE_STRTOUL
- n = strtoul (argv[0], (char **) NULL, 10);
- #elif HAVE_STRTOL
- n = (unsigned long int) strtol (argv[0], (char **) NULL, 10);
- #else
- n = (unsigned long int) atoi (argv[0]);
- #endif
- }
- for (f = 0; n == 0 || f < n; f++)
- {
- switch (rfunc)
- {
- case RFUNC_mpz_urandomb:
- mpz_urandomb (z1, rstate, size);
- if (quiet_flag)
- break;
- if (binout)
- {
- /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
- fprintf (stderr, "gen: binary output for mpz_urandom* is brokenn");
- exit (1);
- }
- else
- {
- mpz_out_str (stdout, output_radix, z1);
- puts ("");
- }
- break;
- case RFUNC_mpz_urandomm:
- mpz_urandomm (z1, rstate, z_mmax);
- if (quiet_flag)
- break;
- if (binout)
- {
- /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
- fprintf (stderr, "gen: binary output for mpz_urandom* is brokenn");
- exit (1);
- }
- else
- {
- mpz_out_str (stdout, output_radix, z1);
- puts ("");
- }
- break;
- case RFUNC_mpf_urandomb:
- mpf_urandomb (f1, rstate, size);
- if (do_exclude)
- if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0)
- break;
- if (quiet_flag)
- break;
- if (binout)
- {
- fprintf (stderr, "gen: binary output for floating point numbers "
- "not implementedn");
- exit (1);
- }
- else
- {
- mpf_out_str (stdout, output_radix, 0, f1);
- puts ("");
- }
- break;
- case RFUNC_rand:
- i = rand ();
- #ifdef FLOAT_OUTPUT
- if (i)
- drand = (double) i / (double) RAND_MAX;
- else
- drand = 0.0;
- if (quiet_flag)
- break;
- if (binout)
- fwrite (&drand, sizeof (drand), 1, stdout);
- else
- printf ("%en", drand);
- #else
- if (quiet_flag)
- break;
- if (binout)
- fwrite (&i, sizeof (i), 1, stdout);
- else
- printf ("%dn", i);
- #endif
- break;
- case RFUNC_random:
- lrand = random ();
- if (lrand)
- drand = (double) lrand / (double) 0x7fffffff;
- else
- drand = 0;
- if (quiet_flag)
- break;
- if (binout)
- fwrite (&drand, sizeof (drand), 1, stdout);
- else
- printf ("%en", drand);
- break;
- default:
- fprintf (stderr, "gen: random function not implementedn");
- exit (1);
- }
- }
- /* clean up */
- switch (rfunc)
- {
- case RFUNC_mpz_urandomb:
- case RFUNC_mpf_urandomb:
- gmp_randclear (rstate);
- break;
- default:
- break;
- }
- mpf_clear (f1);
- mpf_clear (f_xf);
- mpf_clear (f_xt);
- mpz_clear (z1);
- mpz_clear (z_seed);
- return 0;
- }
- static void *debug_dummyz = mpz_dump;
- static void *debug_dummyf = mpf_dump;