From 643c100f1bfc853927f30b32f695a992e0666701 Mon Sep 17 00:00:00 2001 From: colagy Date: Wed, 18 Jan 2023 22:01:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0random,=20=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E4=BA=86next(),=20next=5Fbool()=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/random.rs | 20 +++++++++++-- src/util/random_test.rs | 62 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/util/random.rs b/src/util/random.rs index 805cd3c..331175a 100644 --- a/src/util/random.rs +++ b/src/util/random.rs @@ -26,7 +26,8 @@ impl Random { } } } - /// 获取一个随机数 + + /// 获取一个随机数(u32) /// /// # Examples /// @@ -37,11 +38,23 @@ impl Random { // mod let m = 2147483647_u32; let a = 16807_u32; - let product = self.seed * a; + let product = self.seed.wrapping_mul(a); self.seed = (product >> 31) + (product & m); if self.seed > m { self.seed -= m } self.seed } + + /// 获取一个随机数(bool) + /// + /// # Examples + /// + /// ``` + /// let num = random.next(); + /// ``` + pub fn next_bool(&mut self) -> bool { + self.one_in(2) + } + /// 生成随机数并对n取模 /// /// # Arguments @@ -75,6 +88,7 @@ impl Random { pub fn one_in(&mut self, n: u32) -> bool { (self.next() % n) == 0 } + /// 对随机数进行倾斜 /// /// # Arguments @@ -89,7 +103,7 @@ impl Random { /// let skewed_num = random.skewed(10); /// ``` pub fn skewed(&mut self, max_log: u32) -> u32 { - let bits = 1 << self.uniform(max_log + 1); + let bits = 1_u32.wrapping_shl(self.uniform(max_log + 1)); self.uniform(bits) } } \ No newline at end of file diff --git a/src/util/random_test.rs b/src/util/random_test.rs index 7e7bacc..e442612 100644 --- a/src/util/random_test.rs +++ b/src/util/random_test.rs @@ -1,28 +1,82 @@ mod test { + use std::time::{SystemTime, UNIX_EPOCH}; use crate::util::random::Random; + fn get_timestamp() -> u32 { + let now = SystemTime::now(); + now + .duration_since(UNIX_EPOCH) + .expect("get_current_unix_err") + .as_secs() as u32 + } + + fn get_seed(use_timestamp: bool) -> u32 { + match use_timestamp { + true => get_timestamp(), + false => 32 + } + } + #[test] pub fn test_next() { - let mut random = Random::new(32); + let mut random = Random::new(get_seed(false)); let num = random.next(); println!("{}", num); + assert_eq!(num, 537824); let num2 = random.next(); println!("{}", num2); assert_ne!(num, num2); + assert_eq!(num2, 449273376); } #[test] pub fn test_uniform() { - todo!() + let mut random = Random::new(get_seed(false)); + let num = random.uniform(4); + println!("{}", num); + assert_eq!(num, 0); + + let num2 = random.uniform(5); + println!("{}", num2); + assert_eq!(num2, 1); } #[test] pub fn test_one_in() { - todo!() + let mut random = Random::new(get_seed(false)); + let one_in = random.one_in(2); + println!("{}", one_in); + assert_eq!(one_in, true); + + let mut random = Random::new(get_seed(false) + 1); + let one_in = random.one_in(2); + println!("{}", one_in); + assert_eq!(one_in, false); + } + + #[test] + pub fn test_next_bool() { + let mut random = Random::new(get_seed(false)); + let num = random.next_bool(); + println!("{}", num); + assert_eq!(num, true); + + let mut random = Random::new(get_seed(false) + 1); + let num = random.next_bool(); + println!("{}", num); + assert_eq!(num, false); } #[test] pub fn test_skesed() { - todo!() + let mut random = Random::new(1021); + let base = random.next(); + let num = random.skewed(31); + let uniform = random.uniform(31); + println!("num: {}", num); + println!("base: {}", base); + println!("uniform: {}", uniform); + assert_eq!(num != base, true); + assert_eq!(num != uniform, true); } } \ No newline at end of file -- Gitee