# Module rand::distributions::uniform

source · [−]## Expand description

A distribution uniformly sampling numbers within a given range.

`Uniform`

is the standard distribution to sample uniformly from a range;
e.g. `Uniform::new_inclusive(1, 6)`

can sample integers from 1 to 6, like a
standard die. `Rng::gen_range`

supports any type supported by
`Uniform`

.

This distribution is provided with support for several primitive types
(all integer and floating-point types) as well as `std::time::Duration`

,
and supports extension to user-defined types via a type-specific *back-end*
implementation.

The types `UniformInt`

, `UniformFloat`

and `UniformDuration`

are the
back-ends supporting sampling from primitive integer and floating-point
ranges as well as from `std::time::Duration`

; these types do not normally
need to be used directly (unless implementing a derived back-end).

## Example usage

```
use rand::{Rng, thread_rng};
use rand::distributions::Uniform;
let mut rng = thread_rng();
let side = Uniform::new(-10.0, 10.0);
// sample between 1 and 10 points
for _ in 0..rng.gen_range(1..=10) {
// sample a point from the square with sides -10 - 10 in two dimensions
let (x, y) = (rng.sample(side), rng.sample(side));
println!("Point: {}, {}", x, y);
}
```

## Extending `Uniform`

to support a custom type

To extend `Uniform`

to support your own types, write a back-end which
implements the `UniformSampler`

trait, then implement the `SampleUniform`

helper trait to “register” your back-end. See the `MyF32`

example below.

At a minimum, the back-end needs to store any parameters needed for sampling
(e.g. the target range) and implement `new`

, `new_inclusive`

and `sample`

.
Those methods should include an assert to check the range is valid (i.e.
`low < high`

). The example below merely wraps another back-end.

The `new`

, `new_inclusive`

and `sample_single`

functions use arguments of
type SampleBorrow`SampleBorrow::borrow`

, or you can choose
to copy or clone the value, whatever is appropriate for your type.

```
use rand::prelude::*;
use rand::distributions::uniform::{Uniform, SampleUniform,
UniformSampler, UniformFloat, SampleBorrow};
struct MyF32(f32);
#[derive(Clone, Copy, Debug)]
struct UniformMyF32(UniformFloat<f32>);
impl UniformSampler for UniformMyF32 {
type X = MyF32;
fn new<B1, B2>(low: B1, high: B2) -> Self
where B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized
{
UniformMyF32(UniformFloat::<f32>::new(low.borrow().0, high.borrow().0))
}
fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
where B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized
{
UniformMyF32(UniformFloat::<f32>::new_inclusive(
low.borrow().0,
high.borrow().0,
))
}
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
MyF32(self.0.sample(rng))
}
}
impl SampleUniform for MyF32 {
type Sampler = UniformMyF32;
}
let (low, high) = (MyF32(17.0f32), MyF32(22.0f32));
let uniform = Uniform::new(low, high);
let x = uniform.sample(&mut thread_rng());
```

## Structs

`UniformSampler`

for `char`

.`UniformSampler`

for `Duration`

.`UniformSampler`

for floating-point types.`UniformSampler`

for integer types.## Traits

`Borrow`

but implemented
only for SampleUniform and references to SampleUniform in
order to resolve ambiguity issues.`UniformSampler`

for the sampling type.