On changing rand(3) to random(3) in awk(1)
Vitaly Magerya
vmagerya at gmail.com
Thu Aug 28 16:24:02 UTC 2014
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).
More information about the freebsd-hackers
mailing list