Quote:

> As I understand it Perl calls the standard rand() and srand() functions

> which are pseudo-random generators. If you seed the sequence with:

> srand(timeofday) or something similar, you can scramble the sequence to

> some extent--but it will eventually _repeat_.

Well, no duh. The computer is a finite machine. If you leave the

computer alone, its entire state will eventually repeat. The only way

around that is to have some external source of random numbers that

comes from something much more complicated than a computer. The usual

example is a geiger counter device that's measuring the background

radiation; current physical theories suggest that this is random even

in principle.

`rand' only produces 32 bits of output. In typical implementations,

each value depends only on the previous value. The code typically

looks something like this:

static int rand_seed;

int rand(void) {

unsigned long t = rand_seed * something + something_else;

randno = t % INT_MAX;

return rand_seed;

}

void srand(unsigned s) {

rand_seed = s;

}

(The `perl' version of `rand' maps this [0 .. 2^32) range of integers

onto a [0, 1) range of fractions, probably by dividing everything by

2^32.)

The value that `rand' produces depends only on the value that it

produced last time you called it (or the seed you gave to srand, which

is the same thing). That means that there is a fixed sequence of

numbers, and rand will always give you the numbers from the sequence

one at a time, in order. When it gets to the end, it starts over at

the beginning. All `srand' does is tell `rand' where in the sequence

to start giving you numbers.

The sequence can contain at most 2^32 different values, because that's

all the ints that there are. Therefore, `rand's period is at most 2^32.

Quote:

> And don't do this: srand(rand()); This, as I understand it,

> actually makes the sequence _less_ random (or shortens the period).

The `rand' call comes before the `srand', and so `rand' gets called

before you seed it, and so that `rand' call will produce the same

value every time you run your program. That's the value that you're

seeding with ,and if the seed is the same every time, the sequence of

numbers you get frmo `rand' will be too. So having

srand(rand())

at the beginning of your program isn't any more useful than

srand(1)

. Since `srand(1)' is always there whether you put it in or not, you

might as well leave it out.

If you meant that you would do `srand(rand())' after *every* call to

rand, it is likely to reduce the period. `srand(rand)' never does

anything at all. It sets the seed to whatever random number is

produced by `rand'; but `rand' itself just did this anyway, so the

seed was already set before you called `srand'. `srand' just set the

seed to whatever it was already. So this line has no effect; you're

calling `rand' and throwing the result away.

But if you always call `rand' twice, use the first value, and throw

the second one away, you're only getting half of the values in the

sequence. You're getting the first, third, etc., and throwing away

the second, fourth, etc. If `rand()' had an even period, like 2^32,

you've just cut that period in half, to 2^31. If rand had an odd

period, you'll still get all the numbers, just in a different order.

Quote:

> Thoroughly non-random!

The big deal about `rand' is not that it is `random', in the sense of

being unpredictable. Since `rand' is a computer program, anyone

possessing the source code will find it predictable; this is true of

any possible implementation of `rand' that doesn't depend on measuring

the background radiation or something. If you were surprised to learn

that the values from `rand' would eventually repeat, then you think

that computers are magical, and you need to forget this, since you

work for a software company.

The big deal aboyt `rand' it is `random' in the sense of being

statistically well-distributed. A short subsequence (say, of length

2**16) of the values it produces are likely to be statistically

well-behaved. For example, about half of them will be even numbers.

About half will be smaller than 2**31. Abuot one-fourth will be even

numbers smaller than 2**31. One thing that this implies is that if

you do this silly thing of srand(rand()) after every rand(), so that

you're only getting every other random number, it won't matter too

terribly.

(A peripheral note of possible interest: Knuth points out (I think

it's an exercise in volume 2 of _The Art of Computer Programming_)

that the geiger counter test may *not* have this statistical niceness

property. (!!!))

(Another note: I pulled the 2**16 in the last paragraph out of my

hat. There is a number to use here, but I dno't know what it is; I

suspect that it is at least 2**16.)

--

The night is pleasing to us because, like memory, it erases idle details.