[net.sources.bugs] mz.c

bill@ur-cvsvax.UUCP (Bill Vaughn) (11/07/86)

In article <1125@cit-vax.Caltech.Edu>, trent@cit-vax.Caltech.Edu (Ray Trent) writes:
> In article <823@zen.BERKELEY.EDU> chapman@cory.Berkeley.EDU.UUCP (Brent Chapman) writes:
> >Anyway, the definition of macro oneof() needs to be changed from:
> >    #define oneof(n)    (int)(((long)(n) * rand())/32768)
> >to:
> >    #define oneof(n)    (int)(((long)(n) * (rand() & 0x7fff))/32768)
> 
> I suppose this works...but isn't:
> 
>      #define oneof(n)    (rand() % (n) + 1)
> 
> more intuitive and efficient?
> 

Intuitive? No, not if you know how most rng's work.
Efficient? Maybe.  Trades one multiply and mask for an addition.
Correct? Sorry, but no.

Ray's method uses the low-order bits of the rng which in almost all cases
are much less-random than the high order bits.  In fact they may be
periodic with a period much, much less than the modulus.

As for portability, this is one of those instances where a system library
function is needed.  Otherwise, one needs intimate knowledge of the specifics
of the rng for the system in question.  Just the kind of stuff that
needs to be hidden for portability to work.  It comes down to the fact that
to use a rng correctly one needs to know the maximum value it can generate.

		Bill Vaughn
		Univ. of Rochester
		Rochester, NY
		ur-cvsvax!bill@rochester
		seismo!rochester!ur-cvsvax!bill