Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Aug 2014 15:12:44 +0800
From:      Chenguang Li <horus.li@gmail.com>
To:        Vitaly Magerya <vmagerya@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: On changing rand(3) to random(3) in awk(1)
Message-ID:  <78248D53-D8B6-4135-B900-74E0047F92F1@gmail.com>
In-Reply-To: <53FF574E.1090108@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> <53FF574E.1090108@gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Vitaly Magerya <vmagerya@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-----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?78248D53-D8B6-4135-B900-74E0047F92F1>