Blame stdlib/tst-random.c

Packit 6c4009
/* Test program for random(), srandom(), initstate(), setstate()
Packit 6c4009
   Written by Michael J. Fischer, August 21, 2000
Packit 6c4009
   Placed in the public domain.  */
Packit 6c4009
Packit 6c4009
/* This program primarily tests the correct functioning of srandom()
Packit 6c4009
   and setstate().  The strategy is generate and store a set of random
Packit 6c4009
   sequences, each with a specified starting seed.  Then each sequence
Packit 6c4009
   is regenerated twice and checked against the stored values.
Packit 6c4009
Packit 6c4009
   First they are regenerated one sequence at a time, using srandom()
Packit 6c4009
   to set the initial state.  A discrepency here would suggest that
Packit 6c4009
   srandom() was failing to completely initialize the random number
Packit 6c4009
   generator.
Packit 6c4009
Packit 6c4009
   Second the sequences are regenerated in an interleaved order.
Packit 6c4009
   A state vector is created for each sequence using initstate().
Packit 6c4009
   setstate() is used to switch from sequence to sequence during
Packit 6c4009
   the interleaved generation.  A discrepency here would suggest
Packit 6c4009
   a problem with either initstate() failing to initialize the
Packit 6c4009
   random number generator properly, or the failure of setstate()
Packit 6c4009
   to correctly save and restore state information.  Also, each
Packit 6c4009
   time setstate() is called, the returned value is checked for
Packit 6c4009
   correctness (since we know what it should be).
Packit 6c4009
Packit 6c4009
   Note:  We use default state vector for sequence 0 and our own
Packit 6c4009
   state vectors for the remaining sequences.  This is to give a check
Packit 6c4009
   that the value returned by initstate() is valid and can indeed be
Packit 6c4009
   used in the future.  */
Packit 6c4009
Packit 6c4009
/* Strategy:
Packit 6c4009
   1.  Use srandom() followed by calls on random to generate a set of
Packit 6c4009
       sequences of values.
Packit 6c4009
   2.  Regenerate and check the sequences.
Packit 6c4009
   3.  Use initstate() to create new states.
Packit 6c4009
   4.  Regenerate the sequences in an interleaved manner and check.
Packit 6c4009
*/
Packit 6c4009
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <stdio.h>
Packit 6c4009
Packit 6c4009
const int degree = 128;		/* random number generator degree (should
Packit 6c4009
				   be one of 8, 16, 32, 64, 128, 256) */
Packit 6c4009
const int nseq = 3;		/* number of test sequences */
Packit 6c4009
const int nrnd = 50;		/* length of each test sequence */
Packit 6c4009
const unsigned int seed[3] = { 0x12344321U, 0xEE11DD22U, 0xFEDCBA98 };
Packit 6c4009
Packit 6c4009
void fail (const char *msg, int s, int i) __attribute__ ((__noreturn__));
Packit 6c4009
Packit 6c4009
static int
Packit 6c4009
do_test (void)
Packit 6c4009
{
Packit 6c4009
  long int rnd[nseq][nrnd];	/* pseudorandom numbers */
Packit 6c4009
  char* state[nseq];		/* state for PRNG */
Packit 6c4009
  char* oldstate[nseq];		/* old PRNG state */
Packit 6c4009
  int s;			/* sequence index */
Packit 6c4009
  int i;			/* element index */
Packit 6c4009
Packit 6c4009
  printf ("Begining random package test using %d sequences of length %d.\n",
Packit 6c4009
	  nseq, nrnd);
Packit 6c4009
Packit 6c4009
  /* 1. Generate and store the sequences.  */
Packit 6c4009
  printf ("Generating random sequences.\n");
Packit 6c4009
  for (s = 0; s < nseq; ++s)
Packit 6c4009
    {
Packit 6c4009
      srandom ( seed[s] );
Packit 6c4009
      for (i = 0; i < nrnd; ++i)
Packit 6c4009
	rnd[s][i] = random ();
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* 2. Regenerate and check.  */
Packit 6c4009
  printf ("Regenerating and checking sequences.\n");
Packit 6c4009
  for (s = 0; s < nseq; ++s)
Packit 6c4009
    {
Packit 6c4009
      srandom (seed[s]);
Packit 6c4009
      for (i = 0; i < nrnd; ++i)
Packit 6c4009
	if (rnd[s][i] != random ())
Packit 6c4009
	  fail ("first regenerate test", s, i);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* 3. Create state vector, one for each sequence.
Packit 6c4009
	First state is random's internal state; others are malloced.  */
Packit 6c4009
  printf ("Creating and checking state vector for each sequence.\n");
Packit 6c4009
  srandom (seed[0]);			/* reseed with first seed */
Packit 6c4009
  for (s = 1; s < nseq; ++s)
Packit 6c4009
    {
Packit 6c4009
      state[s] = (char*) malloc (degree);
Packit 6c4009
      oldstate[s] = initstate (seed[s], state[s], degree);
Packit 6c4009
    }
Packit 6c4009
  state[0] = oldstate[1];
Packit 6c4009
Packit 6c4009
  /* Check returned values.  */
Packit 6c4009
  for (s = 1; s < nseq - 1; ++s)
Packit 6c4009
    if (state[s] != oldstate[s + 1])
Packit 6c4009
      fail ("bad initstate() return value", s, i);
Packit 6c4009
Packit 6c4009
  /* 4. Regenerate sequences interleaved and check.  */
Packit 6c4009
  printf ("Regenerating and checking sequences in interleaved order.\n");
Packit 6c4009
  for (i = 0; i < nrnd; ++i)
Packit 6c4009
    {
Packit 6c4009
      for (s = 0; s < nseq; ++s)
Packit 6c4009
	{
Packit 6c4009
	  char *oldstate = (char *) setstate (state[s]);
Packit 6c4009
	  if (oldstate != state[(s + nseq - 1) % nseq])
Packit 6c4009
	    fail ("bad setstate() return value", s, i);
Packit 6c4009
	  if (rnd[s][i] != random ())
Packit 6c4009
	    fail ("bad value generated in interleave test", s, i);
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  printf ("All tests passed!\n");
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
fail (const char *msg, int s, int i)
Packit 6c4009
{
Packit 6c4009
  printf ("\nTest FAILED: ");
Packit 6c4009
  printf ("%s (seq %d, pos %d).\n", msg, s, i);
Packit 6c4009
  exit (1);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#define TEST_FUNCTION do_test ()
Packit 6c4009
#include "../test-skeleton.c"