squares-rnd 3.2.0

Simple and fast counter based non-crypto random generator
Documentation
//!Distribution algorithms

#[derive(Copy, Clone, PartialEq, Eq)]
///The [Bernoulli distribution](https://en.wikipedia.org/wiki/Bernoulli_distribution) `Bernoulli(p)`.
///
///This distribution describes a single boolean random variable, which is true with probability `p` and false with probability `1 - p`.
///It is a special case of the Binomial distribution with `n = 1`.
pub struct Bernoulli {
    ///Probability of success, relative to the maximal integer.
    ///
    ///`u64::MAX` shall indicate 100% (aka 1.0) probability
    pub probability: u64
}

impl Bernoulli {
    const ALWAYS_TRUE: u64 = u64::MAX;
    const SCALE: f64 = 2.0 * (1u64 << 63) as f64;

    #[inline(always)]
    ///Initializes new instances from probability described as float within range of `0.0..=1.0`
    ///
    ///Returns `None` if probability out of bounds
    pub const fn new(probability: f64) -> Option<Self> {
        if probability < 0.0 || probability > 1.0 {
            None
        } else {
            if probability == 1.0 {
                Some(Self {
                    probability: Self::ALWAYS_TRUE
                })
            } else {
                Some(Self {
                    probability: (probability * Self::SCALE) as u64
                })
            }
        }
    }

    #[inline(always)]
    ///Returns `true` if `input` falls within `probability`
    pub const fn is_true(&self, input: u64) -> bool {
        if self.probability == Self::ALWAYS_TRUE {
            true
        } else {
            input < self.probability
        }
    }

    #[inline(always)]
    ///Returns `true` if `rand` next value falls within `probability`
    pub fn sample(&self, rnd: &crate::Rand) -> bool {
        self.is_true(rnd.next_u64())
    }
}