Date: Thu, 28 Aug 2014 12:51:52 +0300 From: Vitaly Magerya <vmagerya@gmail.com> To: Chenguang Li <horus.li@gmail.com>, freebsd-hackers@freebsd.org Subject: Re: On changing rand(3) to random(3) in awk(1) Message-ID: <53FEFBB8.5040305@gmail.com> In-Reply-To: <F70B9462-0898-47EF-AF83-47509F21F84E@gmail.com> References: <F70B9462-0898-47EF-AF83-47509F21F84E@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2014-08-28 09:21, Chenguang Li wrote: > Since the original rand(3) could not provide a fair, "one-shot" randomness in awk(1), > I am writing this to suggest that we change *rand(3) to *random(3), which only requires > modifying a few lines of code[1], but will result in better random number generation. > BTW, OSX & gawk already have this. Previous discussion can be found here[2]. > > What do you think? I think this is a useful change; in particular, srandom(3) seems to do a much better job of coping with sequential seeds than srand(3), which solves a big problem with using 'srand' in our awk. > Index: main.c > =================================================================== > --- main.c (revision 270740) > +++ main.c (working copy) > @@ -74,7 +74,7 @@ > signal(SIGFPE, fpecatch); > > srand_seed = 1; > - srand(srand_seed); > + srandom(srand_seed); > > yyin = NULL; > symtab = makesymtab(NSYMTAB/NSYMTAB); > Index: run.c > =================================================================== > --- run.c (revision 270740) > +++ run.c (working copy) > @@ -1522,7 +1522,7 @@ > break; > case FRAND: > /* in principle, rand() returns something in 0..RAND_MAX */ > - u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX; > + u = (Awkfloat) (random() % RAND_MAX) / RAND_MAX; You should not use RAND_MAX with random(3), since it returns values between 0 and 0x7fffffff (inclusive); RAND_MAX only applies to rand(3). A better patch would be something like this: > - /* in principle, rand() returns something in 0..RAND_MAX */ > - u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX; > + /* random() returns values in [0, 2147483647] */ > + u = (Awkfloat) random() / 2147483648; Also, awk(1) man page should be updated; it currently says: > rand random number on (0,1) ... while it should say: > rand random number on [0,1) > break; > case FSRAND: > if (isrec(x)) /* no argument provided */ > @@ -1530,7 +1530,7 @@ > else > u = getfval(x); > tmp = u; > - srand((unsigned int) u); > + srandom((unsigned int) u); You should probably use 'unsigned long' here. > u = srand_seed; > srand_seed = tmp; > break; Otherwise, the patch looks fine.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53FEFBB8.5040305>