On Tue, Jan 20, 2015 at 11:17:44AM +0000, Michael Savage wrote:
> Hi,
> 
> I'm having trouble generating uniform random doubles in [0,1) with
> arc4random. In games, the snippet:
> 
>       (double) arc4random() / (UINT32_MAX + 1.0)
> 
> crops up multiple times, but that isn't utilising the full precision of
> a double.

What precision does your program need?

> If you do the equivalent with a 64bit random integer:
> 
>       (double) ((uint64_t) arc4random() << 32 | arc4random()) / (UINT64_MAX + 
> 1.0)
> 
> then I can still see two issues. Firstly, we are now putting too much
> precision into a double which is going to add slight bias when it
> rounds. Secondly, `UINT64_MAX + 1.0` probably isn't going to give us
> what we want because of floating point precision.
> 
> Any ideas?

The precision the program needs gives the number of randomness
required. If double is suitable (i.e. if less than 53-bit precision
is needed), then feed it with the needed amount of bits, as you do.

Ex, to get 53 bit precision:

lo = arc4random();
hi = arc4random() & ((1 << (53 - 32)) - 1);

then use:

(double)((uint64_t)hi << 32 | lo) / (1ULL << 53)

HTH

Reply via email to