You could do that too, I suppose. However, where lots of randomness
is not needed (a CGI application that returns random images), I've
actually just skipped a step and applied the modulus to the system
time.
The most obvious example where naïve pseudo-random number generators
can pose a problem with poor "lower-order bit randomness", is when you
are choosing between two values.
The following example, on some very simple pseudo-random number
generators, will alternate which hand the ball is in on every guess.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if 1 /* <-- set to 1 to use a naive rand() implementation
(based on the example in the standard, except even more
naive). */
#define rand my_rand
#define srand my_srand
static unsigned int my_rand_state = 1;
int rand(void)
{
my_rand_state = (my_rand_state * 1103515245 + 12345) % 32768;
return (unsigned int)my_rand_state;
}
void srand(unsigned int seed)
{
my_rand_state = seed;
}
#endif /* naive rand */
enum {
LEFT_HAND = 'l',
RIGHT_HAND = 'r',
QUIT_REQUEST = 'q'
};
struct hand {
int letter;
const char *name;
};
const struct hand hands[] = {
{ LEFT_HAND, "left" },
{ RIGHT_HAND, "right" }
};
void
do_seed(void)
{
srand((unsigned int)time(NULL));
}
int
get_response(void)
{
int ret, c;
fputs("> ", stdout);
fflush(stdout);
c = ret = tolower(getchar());
while (c != '\n') {
if (c == EOF)
return QUIT_REQUEST;
c = getchar();
}
return ret;
}
int
main(void)
{
int i;
do_seed();
for (;
{
struct hand h = hands[ rand() % 2 ];
int r;
puts("Guess which hand the ball is in.");
r = get_response();
if (r == QUIT_REQUEST)
return 0;
else if (r != LEFT_HAND && r != RIGHT_HAND) {
puts("Please enter (L)eft, (R)ight or (Q)uit.");
continue;
}
if (r == h.letter)
fputs("You got it! ", stdout);
else
fputs("Nope! ", stdout);
printf("It was in the %s hand.\n", h.name);
}
/* Never reached. */
}