
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@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org