Message-Id: <200002161146.GAA17821@delorie.com> From: "Dieter Buerssner" To: Eli Zaretskii Date: Wed, 16 Feb 2000 12:57:34 +0100 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: Uptime and entropy in DOS CC: djgpp AT delorie DOT com References: <88btpm$128uk$3 AT fu-berlin DOT de> In-reply-to: X-mailer: Pegasus Mail for Win32 (v3.12b) Reply-To: djgpp AT delorie DOT com On 16 Feb 00, at 8:51, Eli Zaretskii wrote: > On 15 Feb 2000, Dieter Buerssner wrote: > > So, if you really need a good RNG, I would suggest to not > > use random(). You might want to do a net search on Marsaglia > > and Mersenne Twister. > > `random' is actually quite good. It is better than `rand', and with > the single exception of the birthday test, it behaves quite well. It > might be not good enough for George Marsaglia, but I bet nobody else > will notice anything bad ;-) Yes, random() is better than rand(). But the birthday test really is a quite simple test. It uses (in its original parameterization in diehard) only about 25000 random numbers, to show really spectacular failure of random(). This test can be seen as a simple Monte-Carlo simulation. I sometimes use this sort of Monte-Carlo simulation, to confirm an analytical formula, I derived. I think such an application is not necessarily uncommon, and random() can be an easy trap. So my suggestion, for mildly serious usage or random numbers, would still be, to stay away from random(). (And for portability reasons, also. But this can be circumvented, as you noted, by copying the source). Let me give an alternative, suggested by Marsaglia, that is almost as fast as random(), and should be portable between gcc platforms (and C99 platforms). static unsigned long long zseed=0x1234567887654321ULL; /* Multiply with carry RNG, returns 32 bit random numbers */ unsigned long mwc32_rand(void) { unsigned long l1, l2; l1 = zseed&0xffffffffUL; l2 = zseed>>32; zseed=l2+(unsigned long long)l1*999996864UL; return (unsigned long)zseed&0xffffffffUL; } void seed_mwc32(unsigned long s) { zseed = (unsigned long long)(s&0xffffffffUL) +(((unsigned long long)12345)<<32); } > Of course, if someone needs to write a multidimensional Monte-Carlo > simulation whose results will be used in safety-related applications, > then they had better used the best RNG they can get (and run their > program with several different RNGs to see the difference); these > applications *will* need the latest RNGs by Marsaglia. I would not suggest, to use above routine in such an application, either, without havy testing. And of course, cryptographic application are much more demanding. > > When rand_type = 0, BSD random produces very bad random numbers with > > an alternating least significant bit. > > Yes, but you can only get to this mode if you hack the sources of > `random'. (Not too serious, and not very likely to be used this way) Test the following program some day, but please don't hack sources of random() first :-) #include #include int main(void) { static char state[] = {12,121,2,98,67,101,8,45}; int i; initstate(123, state, sizeof state); for (i=0; i<30; i++) printf("%d,", (int)(random()&1)); printf("\n"); return 1; /* :-) */ } Regards, Dieter