Bounds of Random.float (exclusive vs inclusive)

@octachron already gave detailed replies, but just to summarize:

  • The current implementation of Random.float 1.0 guarantees 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 x is x *. Random.float 1.0, so FP rounding can produce the values 0.0 and x, albeit with very low probability (if x is 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.float standard 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.