pub struct Uniform<T: SampleUniform>(_);
Expand description

Sample values uniformly between two bounds.

Uniform values can be constructed from a Range or RangeInclusive. See below for a demonstration.

Steps are taken to avoid bias which might be present in naive implementations; for example rng.next::<u8>() % 170 samples from the interval [0, 170) but is twice as likely to select numbers less than 85 than other values. Further, the implementations here give more weight to the high bits generated by the Rng than the low bits, since with some Rngs the low bits are of lower quality than the high bits.

Implementations must sample within the given interval. It is a bug if an implementation returns a result outside the requested interval.

For one-off samples see also: Random::range for convenient samples directly from the Rng. For more than one sample it is recommended to reuse the Uniform instance.

Examples

use urandom::distributions::{Distribution, Uniform};

let between = Uniform::from(10..10000);
let mut rng = urandom::new();
let mut sum = 0;
for _ in 0..1000 {
	sum += between.sample(&mut rng);
}
println!("{}", sum);

Custom implementations

Different types may have completely different uniform sampling implementations (such as the integers vs floating point types). Start by creating a custom sampler struct which will later be linked to the Uniform type.

For your custom sampler implement Distribution for your custom type and UniformSampler to add constructors to it.

Once that’s done you can specify that your custom type uses your custom sampler by implementing SampleUniform and pointing its associated Sampler type to your custom sampler.

use urandom::{Distribution, Random, Rng};
use urandom::distributions::{SampleUniform, UniformFloat, UniformSampler};

// The custom type for which to implement uniform sampling.
struct MyF32(f32);

// The custom sampler for the type.
struct UniformMyF32(UniformFloat<f32>);

// Add constructors for your sampler.
impl UniformSampler<MyF32> for UniformMyF32 {
	fn new(low: MyF32, high: MyF32) -> Self {
		UniformMyF32(UniformFloat::new(low.0, high.0))
	}
	fn new_inclusive(low: MyF32, high: MyF32) -> Self {
		UniformMyF32(UniformFloat::new_inclusive(low.0, high.0))
	}
}

// Make it a Distribution.
impl Distribution<MyF32> for UniformMyF32 {
	fn sample<R: Rng + ?Sized>(&self, rng: &mut Random<R>) -> MyF32 {
		MyF32(self.0.sample(rng))
	}
}

// Tell everyone where to find the uniform sampler for your type.
impl SampleUniform for MyF32 {
	type Sampler = UniformMyF32;
}

// Now it can be used to generate random samples.
let mut rng = urandom::new();
let value = rng.range(MyF32(13.0)..MyF32(42.0));
assert!(value.0 >= 13.0 && value.0 < 42.0);

Trait Implementations

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Generate a random value of T, using rng as the source of randomness.
Converts to this type from the input type.
Converts to this type from the input type.
Create a new instance which samples uniformly from the half-open range [low, high) (excluding high). May panic if low >= high. Read more
Create a new instance which samples uniformly from the closed range [low, high] (inclusive). May panic if low > high. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.