1#![cfg_attr(not(feature = "std"), no_std)]
31
32use fastrand as fr;
33use paste::paste;
34
35#[cfg(feature = "std")]
36mod global_functions;
37
38#[cfg(feature = "std")]
39pub use global_functions::*;
40
41#[cfg(test)]
42mod float_utils;
43
44#[derive(Clone)]
46pub struct Wdg(fr::Rng);
47
48macro_rules! int {
49 ($self:tt, [$($t:ty),+ $(,)?]) => {
50 $(
51 int_inner!($self, $t);
52 )+
53 };
54}
55
56macro_rules! int_inner {
57 ($self:tt, $t:ty) => {
58 paste! {
59 #[doc = stringify!($t)]
61 pub fn [<special_ $t>](&mut $self) -> $t {
67 match $self.0.u8(0..5) {
68 0 => 0,
69 1 => 1,
70 2 => $t::MAX,
71 3 => -1,
72 4 => $t::MIN,
73 _ => unreachable!(),
74 }
75 }
76
77 #[doc = stringify!($t)]
79 pub fn $t(&mut $self) -> $t {
82 match $self.0.u8(0..3) {
83 0 => $self.[<special_ $t>](),
84 1 => $self.0.$t(2..$t::MAX),
85 2 => $self.0.$t($t::MIN..-1),
86 _ => unreachable!(),
87 }
88 }
89 }
90 };
91}
92
93macro_rules! uint {
94 ($self:tt, [$($t:ty),+ $(,)?]) => {
95 $(
96 uint_inner!($self, $t);
97 )+
98 };
99}
100
101macro_rules! uint_inner {
102 ($self:tt, $t:ty) => {
103 paste! {
104 #[doc = stringify!($t)]
106 pub fn [<special_ $t>](&mut $self) -> $t {
112 match $self.0.u8(0..3) {
113 0 => 0,
114 1 => 1,
115 2 => $t::MAX,
116 _ => unreachable!(),
117 }
118 }
119
120 pub fn $t(&mut $self) -> $t {
121 match $self.0.u8(0..2) {
122 0 => $self.[<special_ $t>](),
123 1 => $self.0.$t(2..$t::MAX),
124 _ => unreachable!(),
125 }
126 }
127 }
128 };
129}
130
131impl Wdg {
132 #[must_use]
133 pub fn with_seed(seed: u64) -> Self {
134 Self(fr::Rng::with_seed(seed))
135 }
136
137 #[must_use]
138 pub fn fork(&mut self) -> Self {
139 Self(self.0.fork())
140 }
141
142 pub fn seed(&mut self, seed: u64) {
143 self.0.seed(seed);
144 }
145
146 pub fn get_seed(&mut self) -> u64 {
147 self.0.get_seed()
148 }
149
150 pub fn nan_f32(&mut self) -> f32 {
156 let sign: u32 = self.0.u32(0..=1) << 31;
157 let exponent: u32 = 0b1111_1111 << 23;
158
159 let mantissa: u32 = self.0.u32(1..(1 << 23));
161
162 let bits = sign | exponent | mantissa;
163 f32::from_bits(bits)
164 }
165
166 pub fn nan_f64(&mut self) -> f64 {
172 let sign: u64 = self.0.u64(0..=1) << 63;
173 let exponent: u64 = 0b0111_1111_1111 << 52;
174
175 let mantissa: u64 = self.0.u64(1..(1 << 52));
177
178 let bits = sign | exponent | mantissa;
179 f64::from_bits(bits)
180 }
181
182 pub fn subnormal_f32(&mut self) -> f32 {
187 let sign: u32 = self.0.u32(0..=1) << 31;
188
189 let mantissa: u32 = self.0.u32(1..(1 << 23));
191
192 let bits = sign | mantissa;
193 f32::from_bits(bits)
194 }
195
196 pub fn subnormal_f64(&mut self) -> f64 {
201 let sign: u64 = self.0.u64(0..=1) << 63;
202
203 let mantissa: u64 = self.0.u64(1..(1 << 52));
205
206 let bits = sign | mantissa;
207 f64::from_bits(bits)
208 }
209
210 pub fn normal_f32(&mut self) -> f32 {
212 let sign: u32 = self.0.u32(0..=1) << 31;
213
214 let exponent: u32 = self.0.u32(0b0000_0001..=0b1111_1110) << 23;
216
217 let mantissa: u32 = self.0.u32(0..=(1 << 23));
218 let bits = sign | exponent | mantissa;
219 f32::from_bits(bits)
220 }
221
222 pub fn normal_f64(&mut self) -> f64 {
224 let sign: u64 = self.0.u64(0..=1) << 63;
225
226 let exponent: u64 = self.0.u64(0b000_0000_0001..=0b111_1111_1110) << 52;
228
229 let mantissa: u64 = self.0.u64(0..=(1 << 52));
230 let bits = sign | exponent | mantissa;
231 f64::from_bits(bits)
232 }
233
234 pub fn special_f32(&mut self) -> f32 {
240 match self.0.u8(0..=11) {
241 0 => 0.0,
242 1 => -0.0,
243 2 => f32::INFINITY,
244 3 => -f32::INFINITY,
245 4 => 1.0,
246 5 => -1.0,
247 6 => f32::MIN,
248 7 => f32::MAX,
249 8 => f32::MIN_POSITIVE,
250 9 => -f32::MIN_POSITIVE,
251 10 => f32::EPSILON,
252 11 => -f32::EPSILON,
253 _ => unreachable!(),
254 }
255 }
256
257 pub fn special_f64(&mut self) -> f64 {
263 match self.0.u8(0..=11) {
264 0 => 0.0,
265 1 => -0.0,
266 2 => f64::INFINITY,
267 3 => -f64::INFINITY,
268 4 => 1.0,
269 5 => -1.0,
270 6 => f64::MIN,
271 7 => f64::MAX,
272 8 => f64::MIN_POSITIVE,
273 9 => -f64::MIN_POSITIVE,
274 10 => f64::EPSILON,
275 11 => -f64::EPSILON,
276 _ => unreachable!(),
277 }
278 }
279
280 pub fn f32(&mut self) -> f32 {
295 match self.0.u8(0..4) {
296 0 => self.normal_f32(),
297 1 => self.subnormal_f32(),
298 2 => self.nan_f32(),
299 3 => self.special_f32(),
300 _ => unreachable!(),
301 }
302 }
303
304 pub fn f64(&mut self) -> f64 {
319 match self.0.u8(0..4) {
320 0 => self.normal_f64(),
321 1 => self.subnormal_f64(),
322 2 => self.nan_f64(),
323 3 => self.special_f64(),
324 _ => unreachable!(),
325 }
326 }
327
328 uint!(self, [u8, u16, u32, u64, u128, usize]);
329
330 int!(self, [i8, i16, i32, i64, i128, isize]);
331}
332
333#[cfg(test)]
334mod test_unit {
335 extern crate std;
336
337 use super::*;
338
339 #[test]
340 fn nan_f32() {
341 let mut gen = Wdg::with_seed(0);
342 assert!(gen.nan_f32().is_nan());
343 }
344
345 #[test]
346 fn nan_f64() {
347 let mut gen = Wdg::with_seed(0);
348 assert!(gen.nan_f64().is_nan());
349 }
350
351 #[test]
352 fn subnormal_f32() {
353 let mut gen = Wdg::with_seed(0);
354 assert!(gen.subnormal_f32().is_subnormal());
355 }
356
357 #[test]
358 fn subnormal_f64() {
359 let mut gen = Wdg::with_seed(0);
360 assert!(gen.subnormal_f64().is_subnormal());
361 }
362
363 #[test]
364 fn normal_f32() {
365 let mut gen = Wdg::with_seed(0);
366 assert!(!gen.normal_f32().is_subnormal());
367 }
368
369 #[test]
370 fn normal_f64() {
371 let mut gen = Wdg::with_seed(0);
372 assert!(!gen.normal_f64().is_subnormal());
373 }
374}
375
376#[cfg(test)]
377mod test_fuzz {
378 extern crate std;
382
383 use crate::float_utils::{f32_exact_eq, f64_exact_eq};
384
385 use super::*;
386
387 #[test]
390 #[ignore]
391 fn nan_f32_is_nan() {
392 let mut gen = Wdg::with_seed(0x0b_65_58_2b_4e_d8_20_fe);
393 for i in 0..(1 << 30) {
394 let num = gen.nan_f32();
395 assert!(num.is_nan(), "{}: {:032b}", i, num.to_bits());
396 }
397 }
398
399 #[test]
400 #[ignore]
401 fn nan_f64_is_nan() {
402 let mut gen = Wdg::with_seed(0x36_44_3e_f8_40_af_6e_49);
403 for i in 0..1 << 30 {
407 let num = gen.nan_f64();
408 assert!(num.is_nan(), "{}: {:064b}", i, num.to_bits());
409 }
410 }
411
412 #[test]
413 fn nan_f32_range() {
414 let mut gen = Wdg::with_seed(0x29_21_f1_bd_8b_a9_c6_b6);
415 let mut coverage: u32 = 0b0;
416 for _ in 0..10000 {
417 let num = gen.nan_f32();
418 coverage |= num.to_bits();
419 }
420
421 assert_eq!(coverage, u32::MAX, "{:032b}", coverage);
423 }
424
425 #[test]
426 fn nan_f64_range() {
427 let mut gen = Wdg::with_seed(0x6f_35_67_53_e6_37_13_c3);
428 let mut coverage: u64 = 0b0;
429 for _ in 0..10000 {
430 let num = gen.nan_f64();
431 coverage |= num.to_bits();
432 }
433
434 assert_eq!(coverage, u64::MAX, "{:064b}", coverage);
436 }
437
438 #[test]
439 #[ignore]
440 fn subnoraml_f32_is_subnormal() {
441 let mut gen = Wdg::with_seed(0x52_58_4a_d1_55_e1_72_10);
442 for i in 0..(1 << 30) {
443 let num = gen.subnormal_f32();
444 assert!(num.is_subnormal(), "{}: {:032b}", i, num.to_bits());
445 }
446 }
447
448 #[test]
449 #[ignore]
450 fn subnormal_f64_is_subnormal() {
451 let mut gen = Wdg::with_seed(0x2d_46_cc_c0_45_c5_ec_03);
452 for i in 0..1 << 30 {
456 let num = gen.subnormal_f64();
457 assert!(num.is_subnormal(), "{}: {:064b}", i, num.to_bits());
458 }
459 }
460
461 #[test]
462 fn subnormal_f32_range() {
463 let mut gen = Wdg::with_seed(0x98_fb_6b_ef_ac_5d_81_f3);
464 let mut coverage: u32 = 0b1111_1111 << 23;
465 for _ in 0..10000 {
466 let num = gen.subnormal_f32();
467 coverage |= num.to_bits();
468 }
469
470 assert_eq!(coverage, u32::MAX, "{:032b}", coverage);
472 }
473
474 #[test]
475 fn subnormal_f64_range() {
476 let mut gen = Wdg::with_seed(0x7a_07_58_14_f4_b8_2f_49);
477 let mut coverage: u64 = 0b111_1111_1111 << 52;
478 for _ in 0..10000 {
479 let num = gen.subnormal_f64();
480 coverage |= num.to_bits();
481 }
482
483 assert_eq!(coverage, u64::MAX, "{:064b}", coverage);
485 }
486
487 #[test]
488 #[ignore]
489 fn noraml_f32_is_not_subnormal() {
490 let mut gen = Wdg::with_seed(0x2c_fe_59_bb_7a_56_28_20);
491 for i in 0..(1 << 30) {
492 let num = gen.normal_f32();
493 assert!(!num.is_subnormal(), "{}: {:032b}", i, num.to_bits());
494 }
495 }
496
497 #[test]
498 #[ignore]
499 fn normal_f64_is_not_subnormal() {
500 let mut gen = Wdg::with_seed(0xa9_26_d1_d9_7b_d7_94_15);
501 for i in 0..1 << 30 {
505 let num = gen.normal_f64();
506 assert!(!num.is_subnormal(), "{}: {:064b}", i, num.to_bits());
507 }
508 }
509
510 #[test]
511 fn normal_f32_range() {
512 let mut gen = Wdg::with_seed(0x15_63_e3_11_09_cb_11_b5);
513 let mut coverage: u32 = 0;
514 for _ in 0..10000 {
515 let num = gen.normal_f32();
516 coverage |= num.to_bits();
517 }
518
519 assert_eq!(coverage, u32::MAX, "{:032b}", coverage);
521 }
522
523 #[test]
524 fn normal_f64_range() {
525 let mut gen = Wdg::with_seed(0x56_e5_19_b1_47_f2_5e_0d);
526 let mut coverage: u64 = 0;
527 for _ in 0..10000 {
528 let num = gen.normal_f64();
529 coverage |= num.to_bits();
530 }
531
532 assert_eq!(coverage, u64::MAX, "{:064b}", coverage);
534 }
535
536 #[test]
537 fn special_f32() {
538 let mut gen = Wdg::with_seed(0x69_1b_e9_82_15_ed_a0_7d);
539 for _ in 0..10000 {
540 gen.special_f32();
541 }
542 }
543
544 #[test]
545 fn special_f64() {
546 let mut gen = Wdg::with_seed(0xf5_31_9e_51_c4_1f_9e_35);
547 for _ in 0..10000 {
548 gen.special_f64();
549 }
550 }
551
552 macro_rules! int_uint {
553 ($($t:ty),+ $(,)?) => {
554 $(
555 int_uint_inner!($t);
556 )+
557 };
558 }
559
560 macro_rules! int_uint_inner {
561 ($t:ty) => {
562 paste! {
563 #[test]
564 pub fn [<special_ $t>]() {
565 let mut gen = Wdg::with_seed(0x29_2d_3a_df_ed_dd_c0_82);
566 for _ in 0..10000 {
567 gen.[<special_ $t>]();
568 }
569 }
570
571 #[test]
572 pub fn $t(){
573 let mut gen = Wdg::with_seed(0x8e_bd_46_37_50_b4_9b_1a);
574 for _ in 0..10000 {
575 gen.$t();
576 }
577 }
578 }
579 };
580 }
581
582 int_uint!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
583
584 #[test]
585 fn special_f32_range() {
586 let mut gen = Wdg::with_seed(0x90_ae_72_03_34_a0_d7_4b);
587 let mut had_infinite = false;
588 let mut had_neg_infinite = false;
589 let mut had_zero = false;
590 let mut had_neg_zero = false;
591 let mut had_one = false;
592 let mut had_neg_one = false;
593 let mut had_min_positive = false;
594 let mut had_max_negative = false;
595 let mut had_epsilon = false;
596 let mut had_neg_epsilon = false;
597 for _ in 0..10000 {
598 let num = gen.special_f32();
599 had_infinite |= f32_exact_eq(num, f32::INFINITY);
600 had_neg_infinite |= f32_exact_eq(num, f32::NEG_INFINITY);
601 had_zero |= f32_exact_eq(num, 0.0);
602 had_neg_zero |= f32_exact_eq(num, -0.0);
603 had_one |= f32_exact_eq(num, 1.0);
604 had_neg_one |= f32_exact_eq(num, -1.0);
605 had_min_positive |= f32_exact_eq(num, f32::MIN_POSITIVE);
606 had_max_negative |= f32_exact_eq(num, -f32::MIN_POSITIVE);
607 had_epsilon |= f32_exact_eq(num, f32::EPSILON);
608 had_neg_epsilon |= f32_exact_eq(num, -f32::EPSILON);
609 }
610 assert!(
611 had_infinite
612 && had_neg_infinite
613 && had_zero
614 && had_neg_zero
615 && had_one
616 && had_neg_one
617 && had_min_positive
618 && had_max_negative
619 && had_epsilon
620 && had_neg_epsilon
621 );
622 }
623
624 #[test]
625 fn special_f64_range() {
626 let mut gen = Wdg::with_seed(0x10_6c_a1_34_a5_6d_03_97);
627 let mut had_infinite = false;
628 let mut had_neg_infinite = false;
629 let mut had_zero = false;
630 let mut had_neg_zero = false;
631 let mut had_one = false;
632 let mut had_neg_one = false;
633 let mut had_min_positive = false;
634 let mut had_max_negative = false;
635 let mut had_epsilon = false;
636 let mut had_neg_epsilon = false;
637 for _ in 0..10000 {
638 let num = gen.special_f64();
639 had_infinite |= f64_exact_eq(num, f64::INFINITY);
640 had_neg_infinite |= f64_exact_eq(num, f64::NEG_INFINITY);
641 had_zero |= f64_exact_eq(num, 0.0);
642 had_neg_zero |= f64_exact_eq(num, -0.0);
643 had_one |= f64_exact_eq(num, 1.0);
644 had_neg_one |= f64_exact_eq(num, -1.0);
645 had_min_positive |= f64_exact_eq(num, f64::MIN_POSITIVE);
646 had_max_negative |= f64_exact_eq(num, -f64::MIN_POSITIVE);
647 had_epsilon |= f64_exact_eq(num, f64::EPSILON);
648 had_neg_epsilon |= f64_exact_eq(num, -f64::EPSILON);
649 }
650 assert!(
651 had_infinite
652 && had_neg_infinite
653 && had_zero
654 && had_neg_zero
655 && had_one
656 && had_neg_one
657 && had_min_positive
658 && had_max_negative
659 && had_epsilon
660 && had_neg_epsilon
661 );
662 }
663
664 #[test]
665 fn f32_range() {
666 let mut gen = Wdg::with_seed(0x7c_65_54_c7_d6_a9_d4_b7);
667
668 let mut had_normal = false;
670 let mut had_subnormal = false;
671 let mut had_nan = false;
672 let mut had_special = false;
673 for _ in 0..10000 {
674 let num = gen.f32();
675 had_normal |= num.is_normal();
676 had_subnormal |= num.is_subnormal();
677 had_nan |= num.is_nan();
678 had_special |= num.is_infinite()
679 | f32_exact_eq(num, 0.0)
680 | f32_exact_eq(num, -0.0)
681 | f32_exact_eq(num, 1.0)
682 | f32_exact_eq(num, -1.0)
683 | f32_exact_eq(num, f32::MIN)
684 | f32_exact_eq(num, f32::MAX)
685 | f32_exact_eq(num, f32::MIN_POSITIVE)
686 | f32_exact_eq(num, -f32::MIN_POSITIVE)
687 | f32_exact_eq(num, f32::EPSILON)
688 | f32_exact_eq(num, -f32::EPSILON);
689 }
690 assert!(had_normal && had_subnormal && had_nan && had_special);
691 }
692
693 #[test]
694 fn f64_range() {
695 let mut gen = Wdg::with_seed(0x9a_a4_ee_0f_08_ba_d9_de);
696
697 let mut had_normal = false;
699 let mut had_subnormal = false;
700 let mut had_nan = false;
701 let mut had_special = false;
702 for _ in 0..10000 {
703 let num = gen.f64();
704 had_normal |= num.is_normal();
705 had_subnormal |= num.is_subnormal();
706 had_nan |= num.is_nan();
707 had_special |= num.is_infinite()
708 | f64_exact_eq(num, 0.0)
709 | f64_exact_eq(num, -0.0)
710 | f64_exact_eq(num, 1.0)
711 | f64_exact_eq(num, -1.0)
712 | f64_exact_eq(num, f64::MIN)
713 | f64_exact_eq(num, f64::MAX)
714 | f64_exact_eq(num, f64::MIN_POSITIVE)
715 | f64_exact_eq(num, -f64::MIN_POSITIVE)
716 | f64_exact_eq(num, f64::EPSILON)
717 | f64_exact_eq(num, -f64::EPSILON);
718 }
719 assert!(had_normal && had_subnormal && had_nan && had_special);
720 }
721}