1fn bit_or(num : f64)->f64{
2 num as i64 as i32 as f64
7}
8#[derive(Copy, Clone)]
20pub struct Mash{
21 n:f64
22}
23impl Mash{
24 pub fn new()->Self{
25 Self { n: 4022871197.0 }
26 }
27 pub fn hash(&mut self, r:&str)->f64{
31 let e = 0.02519603282416938;
32 for s in r.encode_utf16().collect::<Vec<u16>>(){
33 self.n+=s as f64;
34 let f = e*self.n-bit_or(e*self.n);
35 let t = f* bit_or(e*self.n);
36 self.n = 2f64.powi(32) * (t - bit_or(t)) + bit_or(t);
37 }
38 bit_or(self.n) * 2f64.powi(-32)
39 }
40}
41#[derive(Copy, Clone)]
54pub struct Alea{
55 s0: f64, s1: f64,
57 s2: f64,
58 x: f64
59}
60impl Alea {
61 pub fn new(seed: &str)->Self{
63 let mut mash = Mash::new();
64 let mut s0 = mash.hash(" ");
65 let mut s1 = mash.hash(" ");
66 let mut s2 = mash.hash(" ");
67 let x = 1.0;
68 s0 -= mash.hash(&seed);
69 s1 -= mash.hash(&seed);
70 s2 -= mash.hash(&seed);
71 if s0 < 0.0{
72 s0 +=1.0;
73 }
74 if s1 < 0.0{
75 s1 +=1.0;
76 }
77 if s2 < 0.0{
78 s2 +=1.0;
79 }
80 Self { s0,s1,s2,x}
81 }
82 pub fn random(&mut self) -> f64{
84 let y = self.x * 2f64.powi(-32) + self.s0 * 2091639.0;
85 self.s0 = self.s1;
86 self.s1 = self.s2;
87 self.x = bit_or(y);
88 self.s2 = y - self.x;
89 self.s2
90 }
91 pub fn uint32(&mut self)-> u32{
93 (self.random() * 2f64.powi(32)) as u32
94 }
95}
96
97struct MashFast{
98 n:f64
99}
100impl MashFast{
101 pub fn new()->Self{
102 Self { n: 4022871197.0 }
103 }
104 pub fn hash(&mut self, r:&str)->f64{
105 for s in r.encode_utf16().collect::<Vec<u16>>(){
106 self.n += s as f64;
107 let mut hash: f64 = self.n * 0.02519603282416938;
108 self.n = hash.trunc();
109 hash -= self.n;
110 hash *= self.n;
111 self.n = hash.trunc();
112 hash -= self.n;
113 self.n += (hash * 2f64.powi(32)).trunc();
114 }
115 (self.n)* 2f64.powi(-32)
116 }
117}
118#[derive(Copy, Clone)]
121pub struct AleaFast{
122 s0: f64, s1: f64,
124 s2: f64,
125 x: f64
126}
127impl AleaFast {
128 pub fn new(seed: &str)->Self{
130 let mut mash = MashFast::new();
131 let mut s0 = mash.hash(" ");
132 let mut s1 = mash.hash(" ");
133 let mut s2 = mash.hash(" ");
134 let x = 1.0;
135 s0 -= mash.hash(&seed);
136 s1 -= mash.hash(&seed);
137 s2 -= mash.hash(&seed);
138 if s0 < 0.0{
139 s0 +=1.0;
140 }
141 if s1 < 0.0{
142 s1 +=1.0;
143 }
144 if s2 < 0.0{
145 s2 +=1.0;
146 }
147 Self { s0,s1,s2,x}
148 }
149 pub fn random(&mut self) -> f64{
151 let y = self.x * 2f64.powi(-32) + self.s0 * 2091639.0;
152 self.s0 = self.s1;
153 self.s1 = self.s2;
154 self.x = y.trunc();
155 self.s2 = y - self.x;
156 self.s2
157 }
158 pub fn uint32(&mut self)-> u32{
160 (self.random() * 2f64.powi(32)) as u32
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167 #[test]
168 fn bit_or_test() {
169 assert_eq!(bit_or(0.2), 0.0); assert_eq!(bit_or(-1.8), -1.0);
171 assert_eq!(bit_or(1.9), 1.0);
172
173 assert_eq!(bit_or(4294967296.3), 0.0); assert_eq!(bit_or(4294967295.6), -1.0);
175 assert_eq!(bit_or(4294967297.9), 1.0);
176
177 assert_eq!(bit_or(2147483648.9), -2147483648.0); assert_eq!(bit_or(2147483647.3), 2147483647.0);
179 assert_eq!(bit_or(2147483649.1), -2147483647.0);
180 }
181 #[test]
182 fn mash_test(){
183 let mut mash = Mash::new();
184 assert_eq!(mash.hash(""), -0.06335230986587703);
185 let mut mash = Mash::new();
186 assert_eq!(mash.hash(" "), -0.1366710769943893);
187 let mut mash = Mash::new();
188 assert_eq!(mash.hash("frank"), 0.044354382902383804);
189 let mut mash = Mash::new();
190 assert_eq!(mash.hash("cat"), 0.06714190426282585);
191 assert_eq!(mash.hash("rat"), -0.24548634607344866);
192 assert_eq!(mash.hash("bat"), 0.05828765174373984);
193 assert_eq!(mash.hash(" "), 0.03728155279532075);
194 assert_eq!(mash.hash(" "), 0.32264634780585766);
195 assert_eq!(mash.hash(" "), -0.356016042875126);
196 assert_eq!(mash.hash(" "), -0.4360403118189424);
197 }
198 #[test]
199 fn alea_test(){
200 let mut a = Alea::new("frank");
201 assert_eq!(a.random(), 0.8080874253064394);
202 assert_eq!(a.random(), 0.8366762748919427);
203 assert_eq!(a.random(), 0.24404818122275174);
204 let mut a = Alea::new("frank");
205 assert_eq!(a.uint32(), 3470709064);
206 }
207 #[test]
208 fn alea_fast_test(){
209 let mut a = AleaFast::new("frank");
210 assert_eq!(a.random(), 0.8080874253064394);
211 assert_eq!(a.random(), 0.8366762748919427);
212 assert_eq!(a.random(), 0.24404818122275174);
213 let mut a = AleaFast::new("frank");
214 assert_eq!(a.uint32(), 3470709064);
215 }
216}