1 /* gen.c -- Generate pseudorandom numbers.
3 Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
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 3 of the License, or (at your
10 option) any later version.
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.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
23 10 integers 0 <= X < 2^32 generated by mpz_urandomb()
25 $ gen -f mpf_urandomb 10
26 10 real numbers 0 <= X < 1
29 10 integers 0 <= X < 2^127
31 $ gen -f mpf_urandomb -x .9,1 10
32 10 real numbers 0 <= X < .9
35 10 integers, sequence seeded with 1
49 extern int optind, opterr;
60 "usage: gen [-bhpq] [-a n] [-c a,c,m2exp] [-C a,c,m] [-f func] [-g alg] [-m n] [-s n] " \
61 "[-x f,t] [-z n] [n]\n" \
62 " n number of random numbers to generate\n" \
63 " -a n ASCII output in radix n (default, with n=10)\n" \
64 " -b binary output\n" \
65 " -c a,c,m2exp use supplied LC scheme\n" \
66 " -f func random function, one of\n" \
67 " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \
68 " -g alg algorithm, one of mt (default), lc\n" \
69 " -h print this text and exit\n" \
70 " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \
71 " -p print used seed on stderr\n" \
72 " -q quiet, no output\n" \
73 " -s n initial seed (default: output from time(3))\n" \
74 " -x f,t exclude all numbers f <= x <= t\n" \
75 " -z n size in bits of generated numbers (0<= X <2^n) (default 32)\n" \
79 unsigned long int n = 0;
80 unsigned long int seed;
81 unsigned long int m2exp = 0;
82 unsigned int size = 32;
83 int seed_from_user = 0;
84 int ascout = 1, binout = 0, printseed = 0;
85 int output_radix = 10;
86 int lc_scheme_from_user = 0;
91 gmp_randstate_t rstate;
96 mpf_t f_xf, f_xt; /* numbers to exclude from sequence */
97 char *str_xf, *str_xt; /* numbers to exclude from sequence */
98 char *str_a, *str_adder, *str_m;
99 mpz_t z_a, z_m, z_mmax;
100 unsigned long int ul_adder;
104 RFUNC_mpz_urandomb = 0,
109 } rfunc = RFUNC_mpz_urandomb;
110 char *rfunc_str[] = { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb",
117 gmp_randalg_t ralg = RNG_MT;
118 /* Texts for the algorithms. The index of each must match the
119 corresponding algorithm in the enum above. */
120 char *ralg_str[] = { "mt", "lc" };
127 mpz_init_set_ui (z_mmax, 0);
130 while ((c = getopt (argc, argv, "a:bc:f:g:hm:n:pqs:z:x:")) != -1)
136 output_radix = atoi (optarg);
144 case 'c': /* User supplied LC scheme: a,c,m2exp */
145 if (NULL == (str_a = strtok (optarg, ","))
146 || NULL == (str_adder = strtok (NULL, ","))
147 || NULL == (str_m = strtok (NULL, ",")))
149 fprintf (stderr, "gen: bad LC scheme parameters: %s\n", optarg);
153 ul_adder = strtoul (str_adder, NULL, 0);
155 ul_adder = (unsigned long int) strtol (str_adder, NULL, 0);
157 ul_adder = (unsigned long int) atoi (str_adder);
160 if (mpz_init_set_str (z_a, str_a, 0))
162 fprintf (stderr, "gen: bad LC scheme parameter `a': %s\n", str_a);
165 if (ULONG_MAX == ul_adder)
167 fprintf (stderr, "gen: bad LC scheme parameter `c': %s\n",
171 m2exp = atol (str_m);
173 lc_scheme_from_user = 1;
179 for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++)
180 if (!strcmp (optarg, rfunc_str[f]))
187 fputs (usage, stderr);
192 case 'g': /* algorithm */
194 for (f = 0; f < sizeof (ralg_str) / sizeof (*ralg_str); f++)
195 if (!strcmp (optarg, ralg_str[f]))
202 fputs (usage, stderr);
207 case 'm': /* max for mpz_urandomm() */
208 if (mpz_set_str (z_mmax, optarg, 0))
210 fprintf (stderr, "gen: bad max value: %s\n", optarg);
215 case 'p': /* print seed on stderr */
219 case 'q': /* quiet */
223 case 's': /* user provided seed */
224 if (mpz_set_str (z_seed, optarg, 0))
226 fprintf (stderr, "gen: bad seed argument %s\n", optarg);
233 size = atoi (optarg);
236 fprintf (stderr, "gen: bad size argument (-z %u)\n", size);
241 case 'x': /* Exclude. from,to */
243 str_xt = strchr (optarg, ',');
246 fprintf (stderr, "gen: bad exclusion parameters: %s\n", optarg);
256 fputs (usage, stderr);
262 if (! seed_from_user)
263 mpz_set_ui (z_seed, (unsigned long int) time (NULL));
264 seed = mpz_get_ui (z_seed);
267 fprintf (stderr, "gen: seed used: ");
268 mpz_out_str (stderr, output_radix, z_seed);
269 fprintf (stderr, "\n");
272 mpf_set_prec (f1, size);
274 /* init random state and plant seed */
277 case RFUNC_mpf_urandomb:
279 /* Don't init a too small generator. */
280 size = PREC (f1) * GMP_LIMB_BITS;
283 case RFUNC_mpz_urandomb:
284 case RFUNC_mpz_urandomm:
288 gmp_randinit_mt (rstate);
292 if (! lc_scheme_from_user)
293 gmp_randinit_lc_2exp_size (rstate, MIN (128, size));
295 gmp_randinit_lc_2exp (rstate, z_a, ul_adder, m2exp);
299 fprintf (stderr, "gen: unsupported algorithm\n");
303 gmp_randseed (rstate, z_seed);
311 #ifdef __FreeBSD__ /* FIXME */
317 fprintf (stderr, "gen: unsupported algorithm\n");
322 fprintf (stderr, "gen: random function not implemented\n");
326 /* set up excludes */
330 case RFUNC_mpf_urandomb:
332 if (mpf_set_str (f_xf, str_xf, 10) ||
333 mpf_set_str (f_xt, str_xt, 10))
335 fprintf (stderr, "gen: bad exclusion-from (\"%s\") " \
336 "or exclusion-to (\"%s\") string. no exclusion done.\n",
343 fprintf (stderr, "gen: exclusion not implemented for chosen " \
344 "randomization function. all numbers included in sequence.\n");
347 /* generate and print */
351 n = strtoul (argv[0], (char **) NULL, 10);
353 n = (unsigned long int) strtol (argv[0], (char **) NULL, 10);
355 n = (unsigned long int) atoi (argv[0]);
359 for (f = 0; n == 0 || f < n; f++)
363 case RFUNC_mpz_urandomb:
364 mpz_urandomb (z1, rstate, size);
369 /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
370 fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
375 mpz_out_str (stdout, output_radix, z1);
380 case RFUNC_mpz_urandomm:
381 mpz_urandomm (z1, rstate, z_mmax);
386 /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
387 fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
392 mpz_out_str (stdout, output_radix, z1);
397 case RFUNC_mpf_urandomb:
398 mpf_urandomb (f1, rstate, size);
400 if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0)
406 fprintf (stderr, "gen: binary output for floating point numbers "\
407 "not implemented\n");
412 mpf_out_str (stdout, output_radix, 0, f1);
421 drand = (double) i / (double) RAND_MAX;
427 fwrite (&drand, sizeof (drand), 1, stdout);
429 printf ("%e\n", drand);
434 fwrite (&i, sizeof (i), 1, stdout);
443 drand = (double) lrand / (double) 0x7fffffff;
449 fwrite (&drand, sizeof (drand), 1, stdout);
451 printf ("%e\n", drand);
455 fprintf (stderr, "gen: random function not implemented\n");
464 case RFUNC_mpz_urandomb:
465 case RFUNC_mpf_urandomb:
466 gmp_randclear (rstate);
480 static void *debug_dummyz = mpz_dump;
481 static void *debug_dummyf = mpf_dump;