On 08/10/2012 10:06 AM, Eric Blake wrote:
> The alternative I wanted to use was drand48_t() which returns a
double
drand48_r
> in the range 0.0 -> 1.0, with 48 bits of entropy. You could
multiply by
> 'max', and cast to int. But this isn't portable and is not fixed by
> GNULIB.
Might not be too hard to make drand48_r into a gnulib module (harder
than clz, but not intractible, so I'll take a shot at it, but no
promises). Using drand48_r does still hit non-uniformity due to
rounding, but with much smaller fuzz factor (that is, instead of my
example of 50/25/25, you'd be more like 25.000004, 24.999993,
24.999993), which I can live with as being in the noise.
If it wasn't obvious, I was typing this off the cuff rather than giving
actual numbers (still off the cuff, but real numbers would be more like
33.3333334, 33.3333333, 33.3333333 - something that actually adds up to
100% distribution).
No need to do that. -lm already gives us a very nice function: ldexp().
Basically, you take an integer in the range [0,1<<48), then multiply
that by 2**-48 using ldexp().
As we discussed on IRC, no need for drand48[_r], just use
ldexp(virRandomBits(48), -48).
--
Eric Blake eblake(a)redhat.com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org