@octachron already gave detailed replies, but just to summarize:
- The current implementation of
Random.float 1.0guarantees that the result is never 0.0 nor 1.0, which is nice if you’re going to take logarithms afterwards, while not introducing any significant bias. This is not documented, however. - In the general case,
Random.float xisx *. Random.float 1.0, so FP rounding can produce the values 0.0 andx, albeit with very low probability (ifxis not 0.0). - If that’s a problem, you can do rejection sampling:
let rec random_float x =
let r = Random.float x in
if r > 0 && r < x then x else random_float x
- Perhaps the
Random.floatstandard library function should be reimplemented and documented to perform this rejection sampling, instead of the current “let’s draw a non-zero 52-bit integer and scale it to a float in (0,1) then to a float in [0,x]” algorithm.