Skip site navigation (1)Skip section navigation (2)
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>