As I hoped, several suggestions have led to improvements in the code for RNG's I proposed for use in C. (See the thread "Random numbers for C: Some suggestions" in previous postings.) The improved code is listed below.
A question of copyright has also been raised. Unlike DIEHARD, there is no copyright on the code below. You are free to use it in any way you want, but you may wish to acknowledge the source, as a courtesy.
To avoid being cited by the style police, some have suggested using typedef rather than #define in order to replace unsigned long by UL.
Others have pointed out that one cannot be certain of the way that a compiler will evaluate terms in a sum, so using ++c in a term is dangerous. They have offered a version using the comma operator, which ensures that the table index is incremented properly. See LFIB4 and SWB below.
In my earlier work, done in Fortran, I had implemented two 16-bit multiply-with-carry generators, say z and w, as 32-bit integers, with the carry in the top 16 bits, the output in the bottom 16. They were combined by (z<<16)+w. (In Fortran, ishft(z,16)+w.) Such a combination seemed to pass all tests. In the above- mentioned post, I used (z<<16)+(w&65525), and that does not pass all tests. So (z<<16)+w seems preferable; it is used below, providing a MWC that seems to pass all tests.
The generators MWC, KISS, LFIB4 and SWB seem to pass all tests. By themselves, CONG and SHR3 do not, but using CONG+SHR3 provides one of the fastest combinations that satisfy the DIEHARD battery of tests.
Of course, one cannot have absolute confidence in any generator. The choices LFIB4 and SWB have immense periods, are very fast, and pass all tests in DIEHARD, but I am hesitant to rely on them alone---primarily because they come from such simple mod 2^32 arithmetic: four adds in LFIB4 or one subtract-with-borrow in SWB.
The code below provides a variety of in-line generators that seem promising by themselves, and even more so in combination. With them, one may feel fairly confident that combinations will produce results consistent with the underlying probability theory in your applications.
All combinations seem to support the supplemented quote from my 1984 Keynote Address:
A random number generator is like sex; When it's good, it's wonderful, And when it's bad, it's still pretty good.
And when it's bad, try a twosome or threesome.
The C code follows; you may want to snip and save from here--------------------------------------------------:
/* Global static variables: */ static UL z=362436069, w=521288629, jsr=123456789, jcong=380116160; static UL t; static UL x=0,y=0; static unsigned char c=0; /* Random seeds must be used to reset z,w,jsr,jcong and the table t. Here is an example procedure, using KISS: */