Struct urandom::distributions::Standard
source · pub struct Standard;
Expand description
A generic random value distribution, implemented for many primitive types. Usually generates values with a numerically uniform distribution, and with a range appropriate to the type.
Provided implementations
Assuming the provided Rng
is well-behaved, these implementations generate values with the following ranges and distributions:
- Integers (
i32
,u32
,isize
,usize
, etc.): Uniformly distributed over all values of the type. char
: Uniformly distributed over all Unicode scalar values, i.e. all code points in the range0..0x11_0000
, except for the range0xD800..0xE000
(the surrogate code points). This includes unassigned/reserved code points.bool
: Generatestrue
orfalse
, each with equal probability.- Floating point types (
f32
andf64
): Uniformly distributed in the half-open interval[1.0, 2.0)
. See notes below. - Wrapping integers (
Wrapping<T>
), besides the type identical to their normal integer variants.
The Standard
distribution also supports generation of the following compound types where all component types are supported:
- Tuples (up to 12 elements): each element is generated sequentially.
- Arrays (up to 32 elements): each element is generated sequentially;
see also
Random::fill
which supports arbitrary array length for integer types and tends to be faster for u32 and smaller types.
Examples
use urandom::distributions::Standard;
let val: f32 = urandom::new().sample(&Standard);
assert!(val >= 1.0 && val < 2.0, "f32 from [1.0, 2.0): {}", val);
Custom implementations
The Standard
distribution may be implemented for user types as follows:
use urandom::{Random, Rng, Distribution, distributions::Standard};
struct MyF32(f32);
impl Distribution<MyF32> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut Random<R>) -> MyF32 {
MyF32(rng.next())
}
}
Floating point implementation
The floating point implementations for Standard
generate a random value in the half-open interval [1.0, 2.0)
, i.e. including 1.0
but not 2.0
.
The random value is generated by transmuting a random mantissa with a fixed exponent which is very fast and convenient.
The underlying Rng
can optimize generating random floating point values as they don’t need every random bit of the underlying u32
or u64
.
This is equivalent to calling Random::next_f32
and Random::next_f64
directly.
Subtracting 1.0
is an easy way to get a random floating point value in the half-open interval [0.0, 1.0)
but has a small bias
where it will never generate certain floating point values. This is equivalent to rng.range(0.0..1.0)
.
See also: Float01
which samples from (0.0, 1.0)
and does not suffer from this bias.