On changing rand(3) to random(3) in awk(1)

Chenguang Li horus.li at gmail.com
Fri Aug 29 07:13:04 UTC 2014


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Vitaly Magerya <vmagerya at gmail.com> wrote:

> 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:

Yes, I've noticed there's a fairness problem, 0 comes out more often. Since
the original code is buggy too, do we need to be compatible with it?

>>        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).

Thanks for pointing that out, I've modified the gist as your suggestion.

Chenguang Li

-----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJUACfzAAoJELG4cS+11lRhIFgQAII3b12r1JO+KPbnXfEdrsoA
SFaRiG/Z6a8gQBpqTdUA4te9wT+FxQO081bipUv2po7Ys4MZOPkSJ8jh0jiZ02NX
Vw95A+8TfUS5CWq78eqiSgP/x9UxomJ20qM5eUlhslRUX/8Lr4tpVQ3gGuCK0i5n
bq3TgbJiNKaHPwSniVCDv2saS3lUGZp1QWxMK4ecwrmXoMlkNRpBygb2zRep2Q9p
L9ccIQXmDZnZV5A/udIieGbvz5Gfk1utbOTwii41d+1j+zeWtkBlaMFDoWtNhqwp
31EIVQonSPTqStDAOptsixfI5O7G0mfa3nk1eDj+dUABg6qQbPtjWlG9uZL3JjZb
A1ESdzlUSyxoOR2zoEkCgadAkMrbaqA2ziZvPB0o/ClwI99j3htUY+a9NJJmk43y
qDQ0rBaQhj5TajUxsRir46sV70hpITBQP6EB4E18zWpT+GtgUkbPpW3CeKNcCuDk
omTL6XZoS2jXyd62m9woDN3txddvU3XBJxiSL0Mo0hpUnwgg6GCtceAVkQvX6mck
bCBZDPYzsIPMY30esJcL+NkLViwbVufthP/E8pWRU4Jn1a4bCrEA+WBkfTRhI53K
Ph9zMVmZyD/SBwzbgi5eHYdAjTLjOAWyYQpPJ4vRQOe4iX9WNOPF36DjbnAUMLl/
f5sCba2r0hxdjksFQsDF
=FBZK
-----END PGP SIGNATURE-----


More information about the freebsd-hackers mailing list