]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gmp/tests/rand/gen.c
Imported gcc-4.4.3
[msp430-gcc.git] / gmp / tests / rand / gen.c
diff --git a/gmp/tests/rand/gen.c b/gmp/tests/rand/gen.c
new file mode 100644 (file)
index 0000000..c3f8c61
--- /dev/null
@@ -0,0 +1,481 @@
+/* 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 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) * BITS_PER_MP_LIMB;
+      /* 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;