-
Notifications
You must be signed in to change notification settings - Fork 430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add API for getting a bool with chance of exactly 1-in-10 or 2-in-3 #491
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -387,7 +387,7 @@ pub trait Rng: RngCore { | |
/// ``` | ||
/// | ||
/// [`Uniform`]: distributions/uniform/struct.Uniform.html | ||
fn gen_range<T: PartialOrd + SampleUniform>(&mut self, low: T, high: T) -> T { | ||
fn gen_range<T: SampleUniform>(&mut self, low: T, high: T) -> T { | ||
T::Sampler::sample_single(low, high, self) | ||
} | ||
|
||
|
@@ -509,7 +509,8 @@ pub trait Rng: RngCore { | |
|
||
/// Return a bool with a probability `p` of being true. | ||
/// | ||
/// This is a wrapper around [`distributions::Bernoulli`]. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please at least mention this in the doc; same with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a comment, so I'll add this back if really desired. However I don't think it's a good idea to promise a particular implementation strategy. That just seems like complicate future arguments regarding if changing the implementation is a breaking change or not. If we want a pointer to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, just a pointer to |
||
/// See also the [`Bernoulli`] distribution, which may be faster if | ||
/// sampling from the same probability repeatedly. | ||
/// | ||
/// # Example | ||
/// | ||
|
@@ -522,15 +523,44 @@ pub trait Rng: RngCore { | |
/// | ||
/// # Panics | ||
/// | ||
/// If `p` < 0 or `p` > 1. | ||
/// If `p < 0` or `p > 1`. | ||
/// | ||
/// [`distributions::Bernoulli`]: distributions/bernoulli/struct.Bernoulli.html | ||
/// [`Bernoulli`]: distributions/bernoulli/struct.Bernoulli.html | ||
#[inline] | ||
fn gen_bool(&mut self, p: f64) -> bool { | ||
let d = distributions::Bernoulli::new(p); | ||
self.sample(d) | ||
} | ||
|
||
/// Return a bool with a probability of `numerator/denominator` of being | ||
/// true. I.e. `gen_ratio(2, 3)` has chance of 2 in 3, or about 67%, of | ||
/// returning true. If `numerator == denominator`, then the returned value | ||
/// is guaranteed to be `true`. If `numerator == 0`, then the returned | ||
/// value is guaranteed to be `false`. | ||
/// | ||
/// See also the [`Bernoulli`] distribution, which may be faster if | ||
/// sampling from the same `numerator` and `denominator` repeatedly. | ||
/// | ||
/// # Panics | ||
/// | ||
/// If `denominator == 0` or `numerator > denominator`. | ||
/// | ||
/// # Example | ||
/// | ||
/// ``` | ||
/// use rand::{thread_rng, Rng}; | ||
/// | ||
/// let mut rng = thread_rng(); | ||
/// println!("{}", rng.gen_ratio(2, 3)); | ||
/// ``` | ||
/// | ||
/// [`Bernoulli`]: distributions/bernoulli/struct.Bernoulli.html | ||
#[inline] | ||
fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool { | ||
let d = distributions::Bernoulli::from_ratio(numerator, denominator); | ||
self.sample(d) | ||
} | ||
|
||
/// Return a random element from `values`. | ||
/// | ||
/// Return `None` if `values` is empty. | ||
|
@@ -1017,4 +1047,21 @@ mod test { | |
(u8, i8, u16, i16, u32, i32, u64, i64), | ||
(f32, (f64, (f64,)))) = random(); | ||
} | ||
|
||
#[test] | ||
fn test_gen_ratio_average() { | ||
const NUM: u32 = 3; | ||
const DENOM: u32 = 10; | ||
const N: u32 = 100_000; | ||
|
||
let mut sum: u32 = 0; | ||
let mut rng = rng(111); | ||
for _ in 0..N { | ||
if rng.gen_ratio(NUM, DENOM) { | ||
sum += 1; | ||
} | ||
} | ||
let avg = (sum as f64) / (N as f64); | ||
assert!((avg - (NUM as f64)/(DENOM as f64)).abs() < 1e-3); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍