1#![doc = include_str!("../README.md")]
2#![no_std]
3
4#[cfg(feature = "std")]
5extern crate std;
6
7use core::num::NonZeroU128;
8
9#[derive(Clone)]
12pub struct Rng { state: NonZeroU128 }
13
14#[inline(always)]
15const fn get_chunk<T, const N: usize>(slice: &[T], offset: usize) -> &[T; N] {
16 assert!(offset <= slice.len() && N <= slice.len() - offset);
17 unsafe { &*(slice.as_ptr().add(offset) as *const [T; N]) }
18}
19
20#[inline(always)]
21fn get_chunk_mut<T, const N: usize>(slice: &mut [T], offset: usize) -> &mut [T; N] {
22 assert!(offset <= slice.len() && N <= slice.len() - offset);
23 unsafe { &mut *(slice.as_mut_ptr().add(offset) as *mut [T; N]) }
24}
25
26#[inline(always)]
27const fn front_chunk<T, const N: usize>(slice: &[T]) -> &[T; N] {
28 get_chunk(slice, 0)
29}
30
31#[inline(always)]
32fn front_chunk_mut<T, const N: usize>(slice: &mut [T]) -> &mut [T; N] {
33 get_chunk_mut(slice, 0)
34}
35
36#[inline(always)]
37const fn hash(x: NonZeroU128) -> NonZeroU128 {
38 const M: u128 = 0x93c4_67e3_7db0_c7a4_d1be_3f81_0152_cb57;
46
47 let x = x.get();
48 let x = x.wrapping_mul(M);
49 let x = x.swap_bytes();
50 let x = x.wrapping_mul(M);
51 let x = x.swap_bytes();
52 let x = x.wrapping_mul(M);
53 unsafe { NonZeroU128::new_unchecked(x) }
54}
55
56impl Rng {
57 pub const fn new(seed: [u8; 15]) -> Self {
61 let x = u64::from_le_bytes(*get_chunk(&seed, 0));
62 let y = u64::from_le_bytes(*get_chunk(&seed, 7));
63 let s = x as u128 | ((y >> 8) as u128) << 64;
64 let s = s | 1 << 120;
65 let s = NonZeroU128::new(s).unwrap();
66 Self { state: hash(s) }
67 }
68
69 pub const fn from_u64(seed: u64) -> Self {
73 let s = seed as u128;
74 let s = s | 1 << 64;
75 let s = NonZeroU128::new(s).unwrap();
76 Self { state: hash(s) }
77 }
78
79 #[inline(always)]
82 pub const fn state(&self) -> NonZeroU128 {
83 self.state
84 }
85
86 #[inline(always)]
97 pub const fn from_state(state: NonZeroU128) -> Self {
98 Self { state }
99 }
100
101 #[cfg(feature = "getrandom")]
105 #[inline(never)]
106 #[cold]
107 pub fn from_operating_system() -> Self {
108 let mut buf = [0; 16];
109 getrandom::fill(&mut buf).expect("getrandom::fill failed!");
110 let s = u128::from_le_bytes(buf);
111 let s = s | 1;
112 let s = NonZeroU128::new(s).unwrap();
113 Self { state: s }
114 }
115
116 #[inline(always)]
120 pub fn split(&mut self) -> Self {
121 let x = self.u64();
122 let y = self.u64();
123 let s = x as u128 ^ (y as u128) << 64;
124 let s = s | 1;
125 let s = NonZeroU128::new(s).unwrap();
126 Self { state: s }
127 }
128
129 #[inline(always)]
136 pub fn bernoulli(&mut self, p: f64) -> bool {
137 let x = self.u64();
146 let e = 1022 - x.trailing_zeros() as u64;
147 let t = f64::from_bits((e << 52) + (x >> 12));
148 t < p
149 }
150
151 #[inline(always)]
154 pub fn bool(&mut self) -> bool {
155 self.i64() < 0
156 }
157
158 #[inline(always)]
161 pub fn i32(&mut self) -> i32 {
162 self.u64() as i32
163 }
164
165 #[inline(always)]
168 pub fn i64(&mut self) -> i64 {
169 self.u64() as i64
170 }
171
172 #[inline(always)]
175 pub fn u32(&mut self) -> u32 {
176 self.u64() as u32
177 }
178
179 #[inline(always)]
182 pub fn u64(&mut self) -> u64 {
183 let s = self.state.get();
184 let x = s as u64;
185 let y = (s >> 64) as u64;
186 let u = y ^ y >> 19;
187 let v = x ^ y.rotate_right(7);
188 let w = x as u128 * x as u128;
189 let z = y.wrapping_add(w as u64 ^ (w >> 64) as u64);
190 let s = u as u128 ^ (v as u128) << 64;
191 self.state = unsafe { NonZeroU128::new_unchecked(s) };
192 z
193 }
194
195 #[inline(always)]
200 pub fn bounded_u32(&mut self, n: u32) -> u32 {
201 let x = self.u64() as u128;
204 let y = self.u64() as u128;
205 let n = n as u128;
206 let u = x * n + x >> 64;
207 let v = y * n + y;
208 let z = u + v >> 64;
209 z as u32
210 }
211
212 #[inline(always)]
217 pub fn bounded_u64(&mut self, n: u64) -> u64 {
218 let x = self.u64() as u128;
232 let y = self.u64() as u128;
233 let n = n as u128;
234 let u = x * n + x >> 64;
235 let v = y * n + y;
236 let z = u + v >> 64;
237 z as u64
238 }
239
240 #[inline(always)]
246 pub fn between_i32(&mut self, lo: i32, hi: i32) -> i32 {
247 self.between_u32(lo as u32, hi as u32) as i32
248 }
249
250 #[inline(always)]
256 pub fn between_i64(&mut self, lo: i64, hi: i64) -> i64 {
257 self.between_u64(lo as u64, hi as u64) as i64
258 }
259
260 #[inline(always)]
266 pub fn between_u32(&mut self, lo: u32, hi: u32) -> u32 {
267 lo.wrapping_add(self.bounded_u32(hi.wrapping_sub(lo)))
268 }
269
270 #[inline(always)]
276 pub fn between_u64(&mut self, lo: u64, hi: u64) -> u64 {
277 lo.wrapping_add(self.bounded_u64(hi.wrapping_sub(lo)))
278 }
279
280 #[inline(always)]
293 pub fn f32(&mut self) -> f32 {
294 let x = self.i64();
295 let x = f32::from_bits(0x2000_0000) * x as f32;
296 f32::from_bits(0x7fff_ffff & x.to_bits())
297 }
298
299 #[inline(always)]
312 pub fn f64(&mut self) -> f64 {
313 let x = self.i64();
319 let x = f64::from_bits(0x3c00_0000_0000_0000) * x as f64;
320 f64::from_bits(0x7fff_ffff_ffff_ffff & x.to_bits())
321 }
322
323 #[inline(always)]
324 fn bytes_inlined(&mut self, dst: &mut [u8]) {
325 let mut dst = dst;
326
327 if dst.len() == 0 {
328 return;
329 }
330
331 while dst.len() >= 17 {
332 let x = self.u64();
333 let y = self.u64();
334 *front_chunk_mut(dst) = x.to_le_bytes();
335 dst = &mut dst[8 ..];
336 *front_chunk_mut(dst) = y.to_le_bytes();
337 dst = &mut dst[8 ..];
338 }
339
340 if dst.len() >= 9 {
341 let x = self.u64();
342 *front_chunk_mut(dst) = x.to_le_bytes();
343 dst = &mut dst[8 ..];
344 }
345
346 let x = self.u64();
347
348 match dst.len() {
349 1 => *front_chunk_mut(dst) = *front_chunk::<u8, 1>(&x.to_le_bytes()),
350 2 => *front_chunk_mut(dst) = *front_chunk::<u8, 2>(&x.to_le_bytes()),
351 3 => *front_chunk_mut(dst) = *front_chunk::<u8, 3>(&x.to_le_bytes()),
352 4 => *front_chunk_mut(dst) = *front_chunk::<u8, 4>(&x.to_le_bytes()),
353 5 => *front_chunk_mut(dst) = *front_chunk::<u8, 5>(&x.to_le_bytes()),
354 6 => *front_chunk_mut(dst) = *front_chunk::<u8, 6>(&x.to_le_bytes()),
355 7 => *front_chunk_mut(dst) = *front_chunk::<u8, 7>(&x.to_le_bytes()),
356 8 => *front_chunk_mut(dst) = *front_chunk::<u8, 8>(&x.to_le_bytes()),
357 _ => unreachable!(),
358 }
359 }
360
361 pub fn bytes(&mut self, dst: &mut [u8]) {
364 self.bytes_inlined(dst);
365 }
366
367 pub fn byte_array<const N: usize>(&mut self) -> [u8; N] {
370 let mut buf = [0; N];
371 self.bytes_inlined(&mut buf);
372 buf
373 }
374}
375
376#[cfg(feature = "rand_core")]
377impl rand_core::RngCore for Rng {
378 #[inline(always)]
379 fn next_u32(&mut self) -> u32 {
380 self.u32()
381 }
382
383 #[inline(always)]
384 fn next_u64(&mut self) -> u64 {
385 self.u64()
386 }
387
388 fn fill_bytes(&mut self, dst: &mut [u8]) {
389 self.bytes(dst)
390 }
391}
392
393#[cfg(feature = "rand_core")]
394impl rand_core::SeedableRng for Rng {
395 type Seed = [u8; 16];
396
397 fn from_seed(seed: Self::Seed) -> Self {
398 let s = u128::from_le_bytes(seed);
399 let s = s | 1;
400 let s = NonZeroU128::new(s).unwrap();
401 Self::from_state(s)
402 }
403
404 fn seed_from_u64(seed: u64) -> Self {
405 Self::from_u64(seed)
406 }
407
408 fn from_rng(rng: &mut impl rand_core::RngCore) -> Self {
409 let x = rng.next_u64();
410 let y = rng.next_u64();
411 let s = x as u128 ^ (y as u128) << 64;
412 let s = s | 1;
413 let s = NonZeroU128::new(s).unwrap();
414 Self::from_state(s)
415 }
416}
417
418#[cfg(feature = "thread_local")]
419pub mod thread_local {
420 use core::cell::Cell;
426 use core::num::NonZeroU128;
427
428 use crate::Rng;
429
430 std::thread_local! {
431 static RNG: Cell<Option<NonZeroU128>> = const {
432 Cell::new(None)
433 };
434 }
435
436 #[inline(always)]
440 fn with<F, T>(f: F) -> T
441 where
442 F: FnOnce(&mut Rng) -> T
443 {
444 RNG.with(|cell| {
445 let mut rng =
446 match cell.get() {
447 None =>
448 Rng::from_operating_system(),
449 Some(s) =>
450 Rng::from_state(s),
451 };
452 let x = f(&mut rng);
453 cell.set(Some(rng.state()));
454 x
455 })
456 }
457
458 pub fn split() -> Rng {
461 with(|rng| rng.split())
462 }
463
464 pub fn bernoulli(p: f64) -> bool {
467 with(|rng| rng.bernoulli(p))
468 }
469
470 pub fn bool() -> bool {
473 with(|rng| rng.bool())
474 }
475
476 pub fn i32() -> i32 {
479 with(|rng| rng.i32())
480 }
481
482 pub fn i64() -> i64 {
485 with(|rng| rng.i64())
486 }
487
488 pub fn u32() -> u32 {
491 with(|rng| rng.u32())
492 }
493
494 pub fn u64() -> u64 {
497 with(|rng| rng.u64())
498 }
499
500 pub fn bounded_u32(n: u32) -> u32 {
503 with(|rng| rng.bounded_u32(n))
504 }
505
506 pub fn bounded_u64(n: u64) -> u64 {
509 with(|rng| rng.bounded_u64(n))
510 }
511
512 pub fn between_i32(lo: i32, hi: i32) -> i32 {
515 with(|rng| rng.between_i32(lo, hi))
516 }
517
518 pub fn between_i64(lo: i64, hi: i64) -> i64 {
521 with(|rng| rng.between_i64(lo, hi))
522 }
523
524 pub fn between_u32(lo: u32, hi: u32) -> u32 {
527 with(|rng| rng.between_u32(lo, hi))
528 }
529
530 pub fn between_u64(lo: u64, hi: u64) -> u64 {
533 with(|rng| rng.between_u64(lo, hi))
534 }
535
536 pub fn f32() -> f32 {
539 with(|rng| rng.f32())
540 }
541
542 pub fn f64() -> f64 {
545 with(|rng| rng.f64())
546 }
547
548 pub fn bytes(dst: &mut [u8]) {
551 with(|rng| rng.bytes(dst))
552 }
553
554 pub fn byte_array<const N: usize>() -> [u8; N] {
557 with(|rng| rng.byte_array())
558 }
559}