]>
Commit | Line | Data |
---|---|---|
3749640d UD |
1 | /* Test program for random(), srandom(), initstate(), setstate() |
2 | Written by Michael J. Fischer, August 21, 2000 | |
3 | Placed in the public domain. */ | |
4 | ||
5 | /* This program primarily tests the correct functioning of srandom() | |
6 | and setstate(). The strategy is generate and store a set of random | |
7 | sequences, each with a specified starting seed. Then each sequence | |
8 | is regenerated twice and checked against the stored values. | |
9 | ||
10 | First they are regenerated one sequence at a time, using srandom() | |
11 | to set the initial state. A discrepency here would suggest that | |
12 | srandom() was failing to completely initialize the random number | |
13 | generator. | |
14 | ||
15 | Second the sequences are regenerated in an interleaved order. | |
16 | A state vector is created for each sequence using initstate(). | |
17 | setstate() is used to switch from sequence to sequence during | |
18 | the interleaved generation. A discrepency here would suggest | |
19 | a problem with either initstate() failing to initialize the | |
20 | random number generator properly, or the failure of setstate() | |
21 | to correctly save and restore state information. Also, each | |
22 | time setstate() is called, the returned value is checked for | |
23 | correctness (since we know what it should be). | |
24 | ||
25 | Note: We use default state vector for sequence 0 and our own | |
26 | state vectors for the remaining sequences. This is to give a check | |
27 | that the value returned by initstate() is valid and can indeed be | |
28 | used in the future. */ | |
29 | ||
30 | /* Strategy: | |
31 | 1. Use srandom() followed by calls on random to generate a set of | |
32 | sequences of values. | |
33 | 2. Regenerate and check the sequences. | |
34 | 3. Use initstate() to create new states. | |
35 | 4. Regenerate the sequences in an interleaved manner and check. | |
36 | */ | |
37 | ||
38 | #include <stdlib.h> | |
39 | #include <stdio.h> | |
40 | ||
41 | const int degree = 128; /* random number generator degree (should | |
42 | be one of 8, 16, 32, 64, 128, 256) */ | |
43 | const int nseq = 3; /* number of test sequences */ | |
44 | const int nrnd = 50; /* length of each test sequence */ | |
45 | const unsigned int seed[3] = { 0x12344321U, 0xEE11DD22U, 0xFEDCBA98 }; | |
46 | ||
bf4de8f3 | 47 | void fail (const char *msg, int s, int i) __attribute__ ((__noreturn__)); |
3749640d | 48 | |
29955b5d AS |
49 | static int |
50 | do_test (void) | |
3749640d UD |
51 | { |
52 | long int rnd[nseq][nrnd]; /* pseudorandom numbers */ | |
53 | char* state[nseq]; /* state for PRNG */ | |
54 | char* oldstate[nseq]; /* old PRNG state */ | |
55 | int s; /* sequence index */ | |
56 | int i; /* element index */ | |
57 | ||
58 | printf ("Begining random package test using %d sequences of length %d.\n", | |
59 | nseq, nrnd); | |
60 | ||
61 | /* 1. Generate and store the sequences. */ | |
62 | printf ("Generating random sequences.\n"); | |
63 | for (s = 0; s < nseq; ++s) | |
64 | { | |
65 | srandom ( seed[s] ); | |
66 | for (i = 0; i < nrnd; ++i) | |
67 | rnd[s][i] = random (); | |
68 | } | |
69 | ||
70 | /* 2. Regenerate and check. */ | |
71 | printf ("Regenerating and checking sequences.\n"); | |
72 | for (s = 0; s < nseq; ++s) | |
73 | { | |
74 | srandom (seed[s]); | |
75 | for (i = 0; i < nrnd; ++i) | |
76 | if (rnd[s][i] != random ()) | |
77 | fail ("first regenerate test", s, i); | |
78 | } | |
79 | ||
80 | /* 3. Create state vector, one for each sequence. | |
81 | First state is random's internal state; others are malloced. */ | |
82 | printf ("Creating and checking state vector for each sequence.\n"); | |
83 | srandom (seed[0]); /* reseed with first seed */ | |
84 | for (s = 1; s < nseq; ++s) | |
85 | { | |
86 | state[s] = (char*) malloc (degree); | |
87 | oldstate[s] = initstate (seed[s], state[s], degree); | |
88 | } | |
89 | state[0] = oldstate[1]; | |
90 | ||
91 | /* Check returned values. */ | |
92 | for (s = 1; s < nseq - 1; ++s) | |
93 | if (state[s] != oldstate[s + 1]) | |
94 | fail ("bad initstate() return value", s, i); | |
95 | ||
96 | /* 4. Regenerate sequences interleaved and check. */ | |
97 | printf ("Regenerating and checking sequences in interleaved order.\n"); | |
98 | for (i = 0; i < nrnd; ++i) | |
99 | { | |
100 | for (s = 0; s < nseq; ++s) | |
101 | { | |
102 | char *oldstate = (char *) setstate (state[s]); | |
103 | if (oldstate != state[(s + nseq - 1) % nseq]) | |
647eb037 | 104 | fail ("bad setstate() return value", s, i); |
3749640d UD |
105 | if (rnd[s][i] != random ()) |
106 | fail ("bad value generated in interleave test", s, i); | |
107 | } | |
108 | } | |
109 | printf ("All tests passed!\n"); | |
110 | return 0; | |
111 | } | |
112 | ||
113 | void | |
114 | fail (const char *msg, int s, int i) | |
115 | { | |
116 | printf ("\nTest FAILED: "); | |
117 | printf ("%s (seq %d, pos %d).\n", msg, s, i); | |
118 | exit (1); | |
119 | } | |
29955b5d AS |
120 | |
121 | #define TEST_FUNCTION do_test () | |
122 | #include "../test-skeleton.c" |