1use apint::{ApInt};
2use bitwidth::{BitWidth};
3use digit::{Digit};
4
5use rand;
6
7impl rand::Rand for Digit {
8 fn rand<R: rand::Rng>(rng: &mut R) -> Digit {
10 Digit(rng.next_u64())
11 }
12}
13
14impl ApInt {
16 pub fn random_with_width(width: BitWidth) -> ApInt {
18 ApInt::random_with_width_using(width, &mut rand::weak_rng())
19 }
20
21 pub fn random_with_width_using<R>(width: BitWidth, rng: &mut R) -> ApInt
26 where R: rand::Rng
27 {
28 let required_digits = width.required_digits();
29 assert!(required_digits >= 1);
30 let random_digits = rng.gen_iter::<Digit>().take(required_digits);
31 ApInt::from_iter(random_digits)
32 .expect("We asserted that `required_digits` is at least `1` or greater
33 so it is safe to assume that `ApInt::from_iter` won't fail.")
34 .into_truncate(width) .expect("`BitWidth::required_digits` returns an upper bound for the
36 number of required digits, so it is safe to truncate.")
37 }
38
39 pub fn randomize(&mut self) {
43 self.randomize_using(&mut rand::weak_rng())
44 }
45
46 pub fn randomize_using<R>(&mut self, rng: &mut R)
51 where R: rand::Rng
52 {
53 self.digits_mut()
54 .zip(rng.gen_iter::<Digit>())
55 .for_each(|(d, r)| *d = r);
56 self.clear_unused_bits();
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn random_with_width_using() {
66 let mut rng = rand::XorShiftRng::new_unseeded();
67 let r = &mut rng;
68 assert_eq!(ApInt::random_with_width_using(BitWidth::w1(), r), ApInt::from_bit(false));
69 assert_eq!(ApInt::random_with_width_using(BitWidth::w8(), r), ApInt::from_u8(140));
70 assert_eq!(ApInt::random_with_width_using(BitWidth::w16(), r), ApInt::from_u16(970));
71 assert_eq!(ApInt::random_with_width_using(BitWidth::w32(), r), ApInt::from_u32(2466290541));
72 assert_eq!(ApInt::random_with_width_using(BitWidth::w64(), r), ApInt::from_u64(16730135874920933484));
73 assert_eq!(ApInt::random_with_width_using(BitWidth::w128(), r), ApInt::from_u128(217725508292902744084870179638383324996));
74 }
75
76 #[test]
77 fn randomize_using() {
78 let mut rng1 = rand::XorShiftRng::new_unseeded();
79 let mut rng2 = rand::XorShiftRng::new_unseeded();
80 let r1 = &mut rng1;
81 let r2 = &mut rng2;
82
83 {
84 let mut randomized = ApInt::from_bit(false);
85 randomized.randomize_using(r1);
86 let new_random = ApInt::random_with_width_using(BitWidth::w1(), r2);
87 assert_eq!(randomized, new_random);
88 }{
89 let mut randomized = ApInt::from_u8(0);
90 randomized.randomize_using(r1);
91 let new_random = ApInt::random_with_width_using(BitWidth::w8(), r2);
92 assert_eq!(randomized, new_random);
93 }{
94 let mut randomized = ApInt::from_u16(0);
95 randomized.randomize_using(r1);
96 let new_random = ApInt::random_with_width_using(BitWidth::w16(), r2);
97 assert_eq!(randomized, new_random);
98 }{
99 let mut randomized = ApInt::from_u32(0);
100 randomized.randomize_using(r1);
101 let new_random = ApInt::random_with_width_using(BitWidth::w32(), r2);
102 assert_eq!(randomized, new_random);
103 }{
104 let mut randomized = ApInt::from_u64(0);
105 randomized.randomize_using(r1);
106 let new_random = ApInt::random_with_width_using(BitWidth::w64(), r2);
107 assert_eq!(randomized, new_random);
108 }{
109 let mut randomized = ApInt::from_u128(0);
110 randomized.randomize_using(r1);
111 let new_random = ApInt::random_with_width_using(BitWidth::w128(), r2);
112 assert_eq!(randomized, new_random);
113 }
114 }
115}