Trait rug::rand::RandGen
[−]
[src]
pub trait RandGen: Send + Sync { fn gen(&mut self) -> u32; fn gen_bits(&mut self, bits: u32) -> u32 { ... } fn seed(&mut self, seed: &Integer) { ... } fn boxed_clone(&self) -> Option<Box<RandGen>> { ... } }
Custom random number generator to be used with
RandState
.
Examples
use rug::Integer; use rug::rand::RandGen; struct SimpleGenerator { seed: u64, } impl RandGen for SimpleGenerator { fn gen(&mut self) -> u32 { self.seed = self.seed.wrapping_mul(6364136223846793005).wrapping_add(1); (self.seed >> 32) as u32 } fn seed(&mut self, seed: &Integer) { self.seed = seed.to_u64_wrapping(); } } let mut rand = SimpleGenerator { seed: 1 }; assert_eq!(rand.gen(), 1481765933); assert_eq!(rand.seed, 6364136223846793006);
Required Methods
fn gen(&mut self) -> u32
Gets a random 32-bit unsigned integer.
Examples
use rug::rand::RandGen; struct SimpleGenerator { seed: u64, } impl RandGen for SimpleGenerator { fn gen(&mut self) -> u32 { self.seed = self.seed.wrapping_mul(6364136223846793005).wrapping_add(1); (self.seed >> 32) as u32 } } let mut rand = SimpleGenerator { seed: 1 }; let first = rand.gen(); assert_eq!(rand.seed, 6364136223846793006); assert_eq!(first, 1481765933); let second = rand.gen(); assert_eq!(rand.seed, 13885033948157127959); assert_eq!(second, 3232861391);
Provided Methods
fn gen_bits(&mut self, bits: u32) -> u32
Gets up to 32 random bits.
The default implementation simply calls the
gen
method once and returns the most
significant required bits.
This method can be overridden to store any unused bits for later use. This can be useful for example if the random number generation process is computationally expensive.
Examples
use rug::rand::RandGen; struct SimpleGenerator { seed: u64, buffer: u64, len: u32, } impl RandGen for SimpleGenerator { fn gen(&mut self) -> u32 { self.gen_bits(32) } fn gen_bits(&mut self, bits: u32) -> u32 { let mut bits = match bits { 0 => return 0, 1...31 => bits, _ => 32, }; let mut ret = 0; if bits > self.len { bits -= self.len; ret |= (self.buffer << bits) as u32; self.seed = self.seed.wrapping_mul(6364136223846793005); self.seed = self.seed.wrapping_add(1); self.buffer = self.seed; self.len = 64; } self.len -= bits; ret |= (self.buffer >> self.len) as u32; self.buffer &= !(!0 << self.len); ret } } let mut rand = SimpleGenerator { seed: 1, buffer: 0, len: 0 }; let full = 6364136223846793006_u64; assert_eq!(rand.gen_bits(16), (full >> 48) as u32); assert_eq!(rand.gen_bits(32), (full >> 16) as u32); assert_eq!(rand.gen_bits(16), full as u32 & 0xffff);
fn seed(&mut self, seed: &Integer)
Seeds the random number generator.
The default implementation of this function does nothing.
Note that the RandState::seed
method will pass its
seed parameter exactly to this function without using it
otherwise.
Examples
use rug::{Assign, Integer}; use rug::rand::{RandGen, RandState}; struct Seed { inner: Integer }; impl RandGen for Seed { fn gen(&mut self) -> u32 { self.inner.to_u32_wrapping() } fn seed(&mut self, seed: &Integer) { self.inner.assign(seed); } } let mut seed = Seed { inner: Integer::from(12) }; let i = Integer::from(12345); { let mut rand = RandState::new_custom(&mut seed); rand.seed(&i); } assert_eq!(seed.inner, i);
Since the seed parameter is only passed to this function and
not used otherwise, with unsafe code you can pass a reference
to anything, or even an isize
or usize
, to the seeding
function.
use rug::Integer; use rug::rand::{RandGen, RandState}; use std::mem; struct Seed { num: isize }; impl RandGen for Seed { fn gen(&mut self) -> u32 { 0x8cef7310 } fn seed(&mut self, seed: &Integer) { // unsafe code to transmute from &Integer to isize self.num = unsafe { mem::transmute(seed) }; } } let mut seed = Seed { num: 15 }; let i = -12345_isize; { // unsafe code to transmute from isize to &Integer let ir = unsafe { mem::transmute(i) }; let mut rand = RandState::new_custom(&mut seed); rand.seed(ir); } assert_eq!(seed.num, i);
fn boxed_clone(&self) -> Option<Box<RandGen>>
Optionally clones the random number generator.
The default implementation returns None
.
Examples
use rug::rand::RandGen; struct SimpleGenerator { seed: u64, } impl RandGen for SimpleGenerator { fn gen(&mut self) -> u32 { self.seed = self.seed.wrapping_mul(6364136223846793005).wrapping_add(1); (self.seed >> 32) as u32 } fn boxed_clone(&self) -> Option<Box<RandGen>> { let other = SimpleGenerator { seed: self.seed }; let boxed = Box::new(other); Some(boxed) } } let mut rand = SimpleGenerator { seed: 1 }; let first = rand.gen(); assert_eq!(rand.seed, 6364136223846793006); assert_eq!(first, 1481765933); let mut other = rand.boxed_clone().unwrap(); let second = rand.gen(); assert_eq!(rand.seed, 13885033948157127959); assert_eq!(second, 3232861391); let second_other = other.gen(); assert_eq!(second_other, 3232861391);