rand/distributions/
integer.rs1use crate::distributions::{Distribution, Standard};
12use crate::Rng;
13use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
14 NonZeroU128};
15
16impl Distribution<u8> for Standard {
17 #[inline]
18 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u8 {
19 rng.next_u32() as u8
20 }
21}
22
23impl Distribution<u16> for Standard {
24 #[inline]
25 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u16 {
26 rng.next_u32() as u16
27 }
28}
29
30impl Distribution<u32> for Standard {
31 #[inline]
32 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u32 {
33 rng.next_u32()
34 }
35}
36
37impl Distribution<u64> for Standard {
38 #[inline]
39 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
40 rng.next_u64()
41 }
42}
43
44impl Distribution<u128> for Standard {
45 #[inline]
46 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u128 {
47 let x = u128::from(rng.next_u64());
49 let y = u128::from(rng.next_u64());
50 (y << 64) | x
51 }
52}
53
54impl Distribution<usize> for Standard {
55 #[inline]
56 #[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
57 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
58 rng.next_u32() as usize
59 }
60
61 #[inline]
62 #[cfg(target_pointer_width = "64")]
63 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
64 rng.next_u64() as usize
65 }
66}
67
68macro_rules! impl_int_from_uint {
69 ($ty:ty, $uty:ty) => {
70 impl Distribution<$ty> for Standard {
71 #[inline]
72 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
73 rng.gen::<$uty>() as $ty
74 }
75 }
76 };
77}
78
79impl_int_from_uint! { i8, u8 }
80impl_int_from_uint! { i16, u16 }
81impl_int_from_uint! { i32, u32 }
82impl_int_from_uint! { i64, u64 }
83impl_int_from_uint! { i128, u128 }
84impl_int_from_uint! { isize, usize }
85
86macro_rules! impl_nzint {
87 ($ty:ty, $new:path) => {
88 impl Distribution<$ty> for Standard {
89 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
90 loop {
91 if let Some(nz) = $new(rng.gen()) {
92 break nz;
93 }
94 }
95 }
96 }
97 };
98}
99
100impl_nzint!(NonZeroU8, NonZeroU8::new);
101impl_nzint!(NonZeroU16, NonZeroU16::new);
102impl_nzint!(NonZeroU32, NonZeroU32::new);
103impl_nzint!(NonZeroU64, NonZeroU64::new);
104impl_nzint!(NonZeroU128, NonZeroU128::new);
105impl_nzint!(NonZeroUsize, NonZeroUsize::new);
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_integers() {
113 let mut rng = crate::test::rng(806);
114
115 rng.sample::<isize, _>(Standard);
116 rng.sample::<i8, _>(Standard);
117 rng.sample::<i16, _>(Standard);
118 rng.sample::<i32, _>(Standard);
119 rng.sample::<i64, _>(Standard);
120 rng.sample::<i128, _>(Standard);
121
122 rng.sample::<usize, _>(Standard);
123 rng.sample::<u8, _>(Standard);
124 rng.sample::<u16, _>(Standard);
125 rng.sample::<u32, _>(Standard);
126 rng.sample::<u64, _>(Standard);
127 rng.sample::<u128, _>(Standard);
128 }
129
130 #[test]
131 fn value_stability() {
132 fn test_samples<T: Copy + core::fmt::Debug + PartialEq>(zero: T, expected: &[T])
133 where Standard: Distribution<T> {
134 let mut rng = crate::test::rng(807);
135 let mut buf = [zero; 3];
136 for x in &mut buf {
137 *x = rng.sample(Standard);
138 }
139 assert_eq!(&buf, expected);
140 }
141
142 test_samples(0u8, &[9, 247, 111]);
143 test_samples(0u16, &[32265, 42999, 38255]);
144 test_samples(0u32, &[2220326409, 2575017975, 2018088303]);
145 test_samples(0u64, &[
146 11059617991457472009,
147 16096616328739788143,
148 1487364411147516184,
149 ]);
150 test_samples(0u128, &[
151 296930161868957086625409848350820761097,
152 145644820879247630242265036535529306392,
153 111087889832015897993126088499035356354,
154 ]);
155 #[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
156 test_samples(0usize, &[2220326409, 2575017975, 2018088303]);
157 #[cfg(target_pointer_width = "64")]
158 test_samples(0usize, &[
159 11059617991457472009,
160 16096616328739788143,
161 1487364411147516184,
162 ]);
163
164 test_samples(0i8, &[9, -9, 111]);
165 }
167}