From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/tests/rand/gen.c | 480 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 gmp-6.3.0/tests/rand/gen.c (limited to 'gmp-6.3.0/tests/rand/gen.c') diff --git a/gmp-6.3.0/tests/rand/gen.c b/gmp-6.3.0/tests/rand/gen.c new file mode 100644 index 0000000..c8e6c67 --- /dev/null +++ b/gmp-6.3.0/tests/rand/gen.c @@ -0,0 +1,480 @@ +/* gen.c -- Generate pseudorandom numbers. + +Copyright 1999, 2000, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU 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 test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://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 +#include +#include +#include +#include +#include +#include + +#if !HAVE_DECL_OPTARG +extern char *optarg; +extern int optind, opterr; +#endif + +#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 generate\n" \ + " -a n ASCII output in radix n (default, with n=10)\n" \ + " -b binary output\n" \ + " -c a,c,m2exp use supplied LC scheme\n" \ + " -f func random function, one of\n" \ + " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \ + " -g alg algorithm, one of mt (default), lc\n" \ + " -h print this text and exit\n" \ + " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \ + " -p print used seed on stderr\n" \ + " -q quiet, no output\n" \ + " -s n initial seed (default: output from time(3))\n" \ + " -x f,t exclude all numbers f <= x <= t\n" \ + " -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: %s\n", 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': %s\n", str_a); + exit (1); + } + if (ULONG_MAX == ul_adder) + { + fprintf (stderr, "gen: bad LC scheme parameter `c': %s\n", + 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: %s\n", 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 %s\n", 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: %s\n", optarg); + exit (1); + } + *str_xt++ = '\0'; + 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 algorithm\n"); + 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 algorithm\n"); +#endif + break; + + default: + fprintf (stderr, "gen: random function not implemented\n"); + 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 broken\n"); + 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 broken\n"); + 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 implemented\n"); + 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 ("%e\n", drand); +#else + if (quiet_flag) + break; + if (binout) + fwrite (&i, sizeof (i), 1, stdout); + else + printf ("%d\n", 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 ("%e\n", drand); + break; + + default: + fprintf (stderr, "gen: random function not implemented\n"); + 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; -- cgit v1.2.3