diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/rand/gen.c | 141 |
1 files changed, 93 insertions, 48 deletions
diff --git a/tests/rand/gen.c b/tests/rand/gen.c index 7532b183b..f19f41c76 100644 --- a/tests/rand/gen.c +++ b/tests/rand/gen.c @@ -3,19 +3,19 @@ /* Examples: $ gen 10 -10 real numbers 0 <= X < 1 generated by mpf_urandomb() +10 integers 0 <= X < 2^32 generated by mpz_urandomb() - $ gen -f mpz_urandomb 10 -10 integers 0 <= X < 2^32 + $ gen -f mpf_urandomb 10 +10 real numbers 0 <= X < 1 - $ gen -f mpz_urandomb -z 127 10 + $ gen -z 127 10 10 integers 0 <= X < 2^127 - $ gen -x .9,1 10 + $ gen -f mpf_urandomb -x .9,1 10 10 real numbers 0 <= X < .9 $ gen -s 1 10 -10 real numbers, sequence seeded with 1 +10 integers, sequence seeded with 1 */ @@ -26,58 +26,68 @@ #include <errno.h> #include <time.h> #include <string.h> -#include <gmp.h> + +#include "gmp.h" + +#define MIN(a, b) (a < b ? a : b) +#define MAX(a, b) (a > b ? a : b) int main (argc, argv) int argc; char *argv[]; { const char usage[] = - "usage: gen [-abchx] [-f func] [-s #] [-z #] n\n" \ - " n number of numbers to generate\n" \ - " -a ASCII output in radix 10 (default)\n" \ + "usage: gen [-bhp] [-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,m use supplied LC scheme\n" \ + " -c a,c,m2exp use supplied LC scheme\n" \ + " -C a,c,m use supplied LC scheme\n" \ " -f func random function, one of\n" \ - " mpz_urandomb (default), mpf_urandomb, rand, random\n" \ - " -g algorithm, one of lc (default), bbs\n" \ + " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \ + " -g alg algorithm, one of lc (default), bbs\n" \ " -h print this text and exit\n" \ - " -p print seed on stderr\n" \ - " -s # initial seed (default: output from time(3))\n" \ - " -z # size in bits of generated integer numbers (0<= X <2^#) \n" \ - " (default 32)\n" \ + " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \ + " -p print used seed on stderr\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; unsigned long int seed; - mpz_t z_seed; - int seed_from_user = 0, - lc_scheme_from_user = 0; + 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; + mpz_t z_seed; mpz_t z1; mpf_t f1; gmp_rand_state s; int c, i; - int ascout = 1, binout = 0, printseed = 0; 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; + 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", "mpf_urandomb", "rand", "random" }; + char *rfunc_str[] = { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb", + "rand", "random" }; gmp_rand_algorithm ralg = GMP_RAND_ALG_DEFAULT; char *ralg_str[] = { "lc", "bbs" }; @@ -88,12 +98,13 @@ int main (argc, argv) mpz_init (z_seed); - while ((c = getopt (argc, argv, "abc:f:g:hn:ps:z:x:")) != -1) + while ((c = getopt (argc, argv, "a:bc:C:f:g:hm:n:ps:z:x:")) != -1) switch (c) { case 'a': ascout = 1; binout = 0; + output_radix = atoi (optarg); break; case 'b': @@ -101,7 +112,8 @@ int main (argc, argv) binout = 1; break; - case 'c': /* User supplied LC scheme: a,c,m */ + case 'c': /* User supplied LC scheme: a,c,m2exp */ + case 'C': /* User supplied LC scheme: a,c,m */ if (NULL == (str_a = strtok (optarg, ",")) || NULL == (str_adder = strtok (NULL, ",")) || NULL == (str_m = strtok (NULL, ","))) @@ -121,16 +133,15 @@ int main (argc, argv) str_adder); exit (1); } - if (mpz_init_set_str (z_m, str_m, 0)) - { - fprintf (stderr, "gen: bad LC scheme parameter `m': %s\n", str_m); - exit (1); - } - + if (c == 'c') + m2exp = atol (str_m); + else + mpz_init_set_str (z_m, str_m, 0); lc_scheme_from_user = 1; break; + case 'f': rfunc = -1; for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++) @@ -161,6 +172,14 @@ int main (argc, argv) } break; + case 'm': /* max for mpz_urandomm() */ + if (mpz_init_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; @@ -210,34 +229,46 @@ int main (argc, argv) exit (1); } - if (!seed_from_user) + 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, 10, z_seed); + mpz_out_str (stderr, output_radix, z_seed); fprintf (stderr, "\n"); } mpf_set_prec (f1, size); - /* plant seed */ + /* init random state and plant seed */ switch (rfunc) { - case RFUNC_mpz_urandomb: case RFUNC_mpf_urandomb: - if (!lc_scheme_from_user) + case RFUNC_mpz_urandomb: + case RFUNC_mpz_urandomm: + if (! lc_scheme_from_user) { - if (gmp_rand_init (s, ralg, size, z_seed)) - { - fprintf (stderr, "gen: invalid algorithm\n"); - exit (1); - } + gmp_rand_init (s, MIN (128, size), ralg); } else - gmp_rand_init_lc (s, size, z_seed, z_a, ul_adder, z_m); + { + if (m2exp != 0) + gmp_rand_init_lc_2exp (s, z_a, ul_adder, m2exp); + else + gmp_rand_init_lc (s, z_a, ul_adder, z_m); + } + + if (gmp_errno != GMP_ERROR_NONE) + { + if (gmp_errno & GMP_ERROR_INVALID_ARGUMENT) + fprintf (stderr, "gen: asking for too big random state\n"); + if (gmp_errno & GMP_ERROR_UNSUPPORTED_ARGUMENT) + fprintf (stderr, "gen: unsupported algorithm\n"); + exit (1); + } + gmp_rand_seed (s, z_seed); break; case RFUNC_rand: @@ -284,23 +315,37 @@ int main (argc, argv) switch (rfunc) { case RFUNC_mpz_urandomb: - mpz_urandomb (z1, size, s); + mpz_urandomb (z1, s, size); + 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, s, z_mmax); if (binout) { /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/ - fprintf (stderr, "gen: binary output for mpz_urandomb is broken\n"); + fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n"); exit (1); } else { - mpz_out_str (stdout, 10, z1); + mpz_out_str (stdout, output_radix, z1); puts (""); } - break; case RFUNC_mpf_urandomb: - mpf_urandomb (f1, s); + mpf_urandomb (f1, s, 0); if (do_exclude) if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0) break; @@ -312,7 +357,7 @@ int main (argc, argv) } else { - mpf_out_str (stdout, 10, 0, f1); + mpf_out_str (stdout, output_radix, 0, f1); puts (""); } break; |