_If_ your rand() is good enough (and there is no guarantee that it is),
you can simply get 30 bits of pseudo-randomness, even using the usual
15-bit rand(), with
long twice_rand(void)
{
return (rand()&32767)<<15 + rand()&32767;
}
and even more by repeating this method. However, I do not recommend
this.
Then install a good random mechanism. For example, the source code
for cokusmt.h and cokusmt.c is included in my nmmalloc.zip package,
and implements the Mersenne twister.
Neither do I recommend the MT for most people and most purposes. Yes, it
is very good, but it is also complex and uses a lot of state. And it's
quite slow, for a PRNG. In other words, if you're running an on-line
casino, it's not good enough (you want _real_ randomness for that); if
you're running nearly anything else, it's too good; AFAICT, the MT is
the thing for you only if you run Monte Carlo simulations of quantum or
astronomical systems.
For most people, I'd recommend using something simpler than MT, yet
better than the Standard example of rand() (which, remember, is a
_minimal_ implementation). For example, in the message to this newsgroup
with Message-ID <S%
[email protected]> (you
should be able to find it on any good news archive, and also on Google
Groups), George Marsaglia talks about a 32-bit-minus-one PRNG which is
not perfect, but very good for most uses, easy to implement, and quite
swift. It's simply this (with seed function added by me):
uint32_t seed=1; /* Must be a 32-bit, unsigned type. Can't be zero,
and won't ever reach zero through this PRNG. */
uint32_t threeshift_srand(const uint32_t newseed)
{
uint32_t oldseed=seed;
if (newseed)
seed=newseed;
return oldseed;
}
/* Returns a PRN between 0 and 2**32 - 1. */
uint32_t threeshift_rand(void)
{
seed^=seed<<13; seed^=seed>>17; seed^=seed<<5;
return seed-1;
}
Even if you don't use that PRNG, a search of posts to this group by
George Marsaglia will probably tell you more about PRNGs than the rest
of us put together could teach you.
Richard