Back to index

glibc  2.9
tst-random.c
Go to the documentation of this file.
00001 /* Test program for random(), srandom(), initstate(), setstate()
00002    Written by Michael J. Fischer, August 21, 2000
00003    Placed in the public domain.  */
00004 
00005 /* This program primarily tests the correct functioning of srandom()
00006    and setstate().  The strategy is generate and store a set of random
00007    sequences, each with a specified starting seed.  Then each sequence
00008    is regenerated twice and checked against the stored values.
00009 
00010    First they are regenerated one sequence at a time, using srandom()
00011    to set the initial state.  A discrepency here would suggest that
00012    srandom() was failing to completely initialize the random number
00013    generator.
00014 
00015    Second the sequences are regenerated in an interleaved order.
00016    A state vector is created for each sequence using initstate().
00017    setstate() is used to switch from sequence to sequence during
00018    the interleaved generation.  A discrepency here would suggest
00019    a problem with either initstate() failing to initialize the
00020    random number generator properly, or the failure of setstate()
00021    to correctly save and restore state information.  Also, each
00022    time setstate() is called, the returned value is checked for
00023    correctness (since we know what it should be).
00024 
00025    Note:  We use default state vector for sequence 0 and our own
00026    state vectors for the remaining sequences.  This is to give a check
00027    that the value returned by initstate() is valid and can indeed be
00028    used in the future.  */
00029 
00030 /* Strategy:
00031    1.  Use srandom() followed by calls on random to generate a set of
00032        sequences of values.
00033    2.  Regenerate and check the sequences.
00034    3.  Use initstate() to create new states.
00035    4.  Regenerate the sequences in an interleaved manner and check.
00036 */
00037 
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 
00041 const int degree = 128;            /* random number generator degree (should
00042                                be one of 8, 16, 32, 64, 128, 256) */
00043 const int nseq = 3;         /* number of test sequences */
00044 const int nrnd = 50;        /* length of each test sequence */
00045 const unsigned int seed[3] = { 0x12344321U, 0xEE11DD22U, 0xFEDCBA98 };
00046 
00047 void fail (const char *msg, int s, int i) __attribute__ ((__noreturn__));
00048 
00049 int
00050 main (void)
00051 {
00052   long int rnd[nseq][nrnd]; /* pseudorandom numbers */
00053   char* state[nseq];        /* state for PRNG */
00054   char* oldstate[nseq];            /* old PRNG state */
00055   int s;                    /* sequence index */
00056   int i;                    /* element index */
00057 
00058   printf ("Begining random package test using %d sequences of length %d.\n",
00059          nseq, nrnd);
00060 
00061   /* 1. Generate and store the sequences.  */
00062   printf ("Generating random sequences.\n");
00063   for (s = 0; s < nseq; ++s)
00064     {
00065       srandom ( seed[s] );
00066       for (i = 0; i < nrnd; ++i)
00067        rnd[s][i] = random ();
00068     }
00069 
00070   /* 2. Regenerate and check.  */
00071   printf ("Regenerating and checking sequences.\n");
00072   for (s = 0; s < nseq; ++s)
00073     {
00074       srandom (seed[s]);
00075       for (i = 0; i < nrnd; ++i)
00076        if (rnd[s][i] != random ())
00077          fail ("first regenerate test", s, i);
00078     }
00079 
00080   /* 3. Create state vector, one for each sequence.
00081        First state is random's internal state; others are malloced.  */
00082   printf ("Creating and checking state vector for each sequence.\n");
00083   srandom (seed[0]);               /* reseed with first seed */
00084   for (s = 1; s < nseq; ++s)
00085     {
00086       state[s] = (char*) malloc (degree);
00087       oldstate[s] = initstate (seed[s], state[s], degree);
00088     }
00089   state[0] = oldstate[1];
00090 
00091   /* Check returned values.  */
00092   for (s = 1; s < nseq - 1; ++s)
00093     if (state[s] != oldstate[s + 1])
00094       fail ("bad initstate() return value", s, i);
00095 
00096   /* 4. Regenerate sequences interleaved and check.  */
00097   printf ("Regenerating and checking sequences in interleaved order.\n");
00098   for (i = 0; i < nrnd; ++i)
00099     {
00100       for (s = 0; s < nseq; ++s)
00101        {
00102          char *oldstate = (char *) setstate (state[s]);
00103          if (oldstate != state[(s + nseq - 1) % nseq])
00104            fail ("bad setstate() return value", s, i);
00105          if (rnd[s][i] != random ())
00106            fail ("bad value generated in interleave test", s, i);
00107        }
00108     }
00109   printf ("All tests passed!\n");
00110   return 0;
00111 }
00112 
00113 void
00114 fail (const char *msg, int s, int i)
00115 {
00116   printf ("\nTest FAILED: ");
00117   printf ("%s (seq %d, pos %d).\n", msg, s, i);
00118   exit (1);
00119 }