Date: Thu, 28 Aug 2014 19:22:38 +0300 From: Vitaly Magerya <vmagerya@gmail.com> To: Chenguang Li <horus.li@gmail.com>, Peter Pentchev <roam@ringlet.net> Cc: freebsd-hackers@freebsd.org Subject: Re: On changing rand(3) to random(3) in awk(1) Message-ID: <53FF574E.1090108@gmail.com> In-Reply-To: <5C40F611-22EB-49E4-8925-37922E771C0F@gmail.com> References: <F70B9462-0898-47EF-AF83-47509F21F84E@gmail.com> <53FEFBB8.5040305@gmail.com> <20140828131526.GA2385@straylight.m.ringlet.net> <5C40F611-22EB-49E4-8925-37922E771C0F@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 08/28/14 16:28, Chenguang Li wrote: > I am using RANDOM_MAX here to maintain the original code structure. > I've updated my patch, please check the gist. Thanks! > jmp_buf env; > extern int pairstack[]; > @@ -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() % RANDOM_MAX) / RANDOM_MAX; > break; > case FSRAND: > if (isrec(x)) /* no argument provided */ OK, so this part is wrong (and it is wrong in the original sources too): this construction generates 0.0 twice as often as it generates other numbers -- both when random() returns 0 and when it returns RANDOM_MAX. The correct construction is this: > case FRAND: > - /* in principle, rand() returns something in 0..RAND_MAX */ > - u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX; > + /* random() returns values in [0, RANDOM_MAX] */ > + u = (Awkfloat) random() / (RANDOM_MAX + 1ul); > break; Note that the "ul" part in "1ul" is vitally important: otherwise there will be an overflow on systems where long is 32 bit wide. Alternatively "1.0" can be used here instead. (Because this overflow may not be obvious in a casual reading, I'm not a fan of defining RANDOM_MAX separately; I personally would insert the actual number here directly).
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53FF574E.1090108>