avx_rand/
lib.rs

1//! avx Rand - Gerador de números aleatórios nativo
2//! Substitui rand - 100% Rust std
3
4use std::cell::RefCell;
5
6thread_local! {
7    static RNG: RefCell<Xoshiro256> = RefCell::new(Xoshiro256::new());
8}
9
10// Xoshiro256** - algoritmo rápido e de qualidade
11struct Xoshiro256 {
12    s: [u64; 4],
13}
14
15impl Xoshiro256 {
16    fn new() -> Self {
17        let seed = Self::seed_from_time();
18        Self::from_seed(seed)
19    }
20
21    fn from_seed(seed: u64) -> Self {
22        let mut s = [0u64; 4];
23        s[0] = seed;
24        s[1] = seed.wrapping_mul(0x9e3779b97f4a7c15);
25        s[2] = seed.wrapping_mul(0xbf58476d1ce4e5b9);
26        s[3] = seed.wrapping_mul(0x94d049bb133111eb);
27        Self { s }
28    }
29
30    fn seed_from_time() -> u64 {
31        use std::time::{SystemTime, UNIX_EPOCH};
32        SystemTime::now()
33            .duration_since(UNIX_EPOCH)
34            .unwrap()
35            .as_nanos() as u64
36    }
37
38    fn next(&mut self) -> u64 {
39        let result = self.s[1].wrapping_mul(5).rotate_left(7).wrapping_mul(9);
40        let t = self.s[1] << 17;
41
42        self.s[2] ^= self.s[0];
43        self.s[3] ^= self.s[1];
44        self.s[1] ^= self.s[2];
45        self.s[0] ^= self.s[3];
46        self.s[2] ^= t;
47        self.s[3] = self.s[3].rotate_left(45);
48
49        result
50    }
51}
52
53pub struct Rng;
54
55impl Rng {
56    pub fn new() -> Self {
57        Self
58    }
59
60    pub fn gen<T: Rand>(&mut self) -> T {
61        T::rand(self)
62    }
63
64    pub fn gen_range<T: RandRange>(&mut self, range: std::ops::Range<T>) -> T {
65        T::rand_range(self, range)
66    }
67
68    fn next_u64(&mut self) -> u64 {
69        RNG.with(|rng| rng.borrow_mut().next())
70    }
71}
72
73impl Default for Rng {
74    fn default() -> Self {
75        Self::new()
76    }
77}
78
79pub trait Rand: Sized {
80    fn rand(rng: &mut Rng) -> Self;
81}
82
83pub trait RandRange: Sized {
84    fn rand_range(rng: &mut Rng, range: std::ops::Range<Self>) -> Self;
85}
86
87impl Rand for u64 {
88    fn rand(rng: &mut Rng) -> Self {
89        rng.next_u64()
90    }
91}
92
93impl Rand for u32 {
94    fn rand(rng: &mut Rng) -> Self {
95        rng.next_u64() as u32
96    }
97}
98
99impl Rand for u16 {
100    fn rand(rng: &mut Rng) -> Self {
101        rng.next_u64() as u16
102    }
103}
104
105impl Rand for u8 {
106    fn rand(rng: &mut Rng) -> Self {
107        rng.next_u64() as u8
108    }
109}
110
111impl Rand for i64 {
112    fn rand(rng: &mut Rng) -> Self {
113        rng.next_u64() as i64
114    }
115}
116
117impl Rand for i32 {
118    fn rand(rng: &mut Rng) -> Self {
119        rng.next_u64() as i32
120    }
121}
122
123impl Rand for f64 {
124    fn rand(rng: &mut Rng) -> Self {
125        let bits = rng.next_u64();
126        let float_bits = (bits >> 12) | 0x3FF0_0000_0000_0000;
127        f64::from_bits(float_bits) - 1.0
128    }
129}
130
131impl Rand for f32 {
132    fn rand(rng: &mut Rng) -> Self {
133        f64::rand(rng) as f32
134    }
135}
136
137impl Rand for bool {
138    fn rand(rng: &mut Rng) -> Self {
139        (rng.next_u64() & 1) == 1
140    }
141}
142
143impl RandRange for u64 {
144    fn rand_range(rng: &mut Rng, range: std::ops::Range<Self>) -> Self {
145        let span = range.end - range.start;
146        range.start + (rng.next_u64() % span)
147    }
148}
149
150impl RandRange for usize {
151    fn rand_range(rng: &mut Rng, range: std::ops::Range<Self>) -> Self {
152        let span = range.end - range.start;
153        range.start + ((rng.next_u64() as usize) % span)
154    }
155}
156
157impl RandRange for u32 {
158    fn rand_range(rng: &mut Rng, range: std::ops::Range<Self>) -> Self {
159        let span = range.end - range.start;
160        range.start + ((rng.next_u64() as u32) % span)
161    }
162}
163
164impl RandRange for i32 {
165    fn rand_range(rng: &mut Rng, range: std::ops::Range<Self>) -> Self {
166        let span = (range.end - range.start) as u32;
167        range.start + ((rng.next_u64() as u32) % span) as i32
168    }
169}
170
171impl RandRange for f64 {
172    fn rand_range(rng: &mut Rng, range: std::ops::Range<Self>) -> Self {
173        let span = range.end - range.start;
174        range.start + f64::rand(rng) * span
175    }
176}
177
178// Funções globais
179pub fn random<T: Rand>() -> T {
180    Rng::new().gen()
181}
182
183pub fn random_range<T: RandRange>(range: std::ops::Range<T>) -> T {
184    Rng::new().gen_range(range)
185}
186
187pub fn shuffle<T>(slice: &mut [T]) {
188    let mut rng = Rng::new();
189    for i in (1..slice.len()).rev() {
190        let j = rng.gen_range(0..i + 1);
191        slice.swap(i, j);
192    }
193}
194
195pub fn seed(seed: u64) {
196    RNG.with(|rng| {
197        *rng.borrow_mut() = Xoshiro256::from_seed(seed);
198    });
199}
200
201#[cfg(test)]
202mod tests {
203    use super::*;
204
205    #[test]
206    fn test_basic_types() {
207        let mut rng = Rng::new();
208        let _u: u64 = rng.gen();
209        let _f: f64 = rng.gen();
210        let _b: bool = rng.gen();
211    }
212
213    #[test]
214    fn test_range() {
215        let mut rng = Rng::new();
216        for _ in 0..100 {
217            let val = rng.gen_range(10..20);
218            assert!(val >= 10 && val < 20);
219        }
220    }
221
222    #[test]
223    fn test_global_functions() {
224        let _v: u32 = random();
225        let v = random_range(5..15);
226        assert!(v >= 5 && v < 15);
227    }
228
229    #[test]
230    fn test_shuffle() {
231        let mut arr = [1, 2, 3, 4, 5];
232        shuffle(&mut arr);
233        assert_eq!(arr.len(), 5);
234    }
235
236    #[test]
237    fn test_seed_determinism() {
238        seed(12345);
239        let mut rng = Rng::new();
240        let v1: u64 = rng.gen();
241
242        seed(12345);
243        let mut rng2 = Rng::new();
244        let v2: u64 = rng2.gen();
245
246        assert_eq!(v1, v2);
247    }
248}
249
250
251
252
253