Why does rand (Rng::gen) have different default ranges for float and int types?
This is more of a general API design question, but rand is the first example I can think of. Consider the following two calls:
let mut rng = thread_rng();
let a: u32 = rng.gen();
let b: f64 = rng.gen();
a will have a value in the range 0..u32::MAX, but b will have a value in 0..1.
While I understand that values in 0..1 are the most useful for floats, we lose a nice property of being able to easily determine the range: instead of always assuming that it's T::MIN..T::MAX for any numeric type T, we can only know the truth by consulting the docs. This may not be an issue when working with specific types, but I can imagine how using it in generic code may be confusing. You also have to remember things like this:
struct Measurement {
id: u64;
temperature: f64;
}
// Generating a value, e.g. in a property-based test
Measurement {
id: rng.gen(),
temperature: rng.gen() // oops, this will never exceed 1 degree
}
This is not the first API I see that does this: C#'s NextDouble also returns a value in 0..1.
My question is: are there some fundamental downsides in alternative approaches, like returning the full range of float values for rng.gen::<f64>()? Or is it purely a matter of optimizing for the most common use case?
Thanks!