The choice of multipliers in linear congruential pseudo-random generators

is far more advanced than just "use a prime". Knuth's volume 2,

Seminumerical

Algorithms, devotes a lot of pages to this. Table 1 lists several

generators,

mostly good, but with one or two "bad" examples. Borrow a copy,

use one of the good ones.

Also, mod 1601, even with an excellent multiplier will give a poor

pseudo-random stream because the modulus is WAY too low.

Note that many of the generators in Knuth's Table 1 have

moduli of (2^n)-1 or (2^n)+1. For either of these cases

assembly implementation is trivial if n=word width. For

a n-bit by n-bit multiplication, the high n bits of the 2n-bit

result are either added to or subtracted from the low n bits.

This kind of operation, while difficult to implement efficiently

in most HLLs, is trivial in assembly.

I would recommend choosing one of the table entries with

2^32 +/- 1. Smaller moduli are asking for trouble.

Previous rand (or seed) in EAX

multiplier in EDX

offset (if any) in ECX

----------------

imul eax,edx

add eax,ecx

sub eax,edx ; mod (2^32)+1

----------------

imul eax,edx

add eax,ecx

add eax,edx ; mod (2^32)-1

result will smash EDX and leave new rand in EAX. Note NO idiv's.

--

Kevin G. Rhoads, Ph.D. (Linearity is a convenient fiction.)