module std::math::random; // Move ODD_PHI into a shared module const ODD_PHI128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835; const ODD_PHI64 @local = 0x9e3779b97f4a7c15; const ODD_PHI32 @local = 0x9e3779b9; const ODD_PHI16 @local = 0x9e37; const ODD_PHI8 @local = 0x9f; // Msws128 struct Msws128Random { uint128 state0, state1; uint128 weyl0, weyl1; } fn void Msws128Random.set_seed(&self, char[] input) : Random { *self = bitcast(random::make_seed(uint128[4], input), Msws128Random); } fn uint128 Msws128Random.next_int128(&self) { uint128 s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; self.state0 = self.state0.rotr(64); self.weyl0 += ODD_PHI128; self.state1 = self.state1 * self.state1 + self.weyl1; uint128 s1 = self.state1; self.state1 = self.state1.rotr(64); self.weyl1 -= ODD_PHI128; return s0 + s1; } /** * @require bytes.len > 0 **/ fn void Msws128Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int128, bytes); fn ulong Msws128Random.next_long(&self) : Random => (ulong)self.next_int128(); fn uint Msws128Random.next_int(&self) : Random => (uint)self.next_int128(); fn ushort Msws128Random.next_short(&self) : Random => (ushort)self.next_int128(); fn char Msws128Random.next_byte(&self) : Random => (char)self.next_int128(); // Msws64 struct Msws64Random { ulong state0, state1; ulong weyl0, weyl1; } fn void Msws64Random.set_seed(&self, char[] input) : Random { *self = bitcast(random::make_seed(ulong[4], input), Msws64Random); } fn ulong Msws64Random.next_long(&self) : Random { ulong s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; self.state0 = self.state0.rotr(32); self.weyl0 += ODD_PHI64; self.state1 = self.state1 * self.state1 + self.weyl1; ulong s1 = self.state1; self.state1 = self.state1.rotr(32); self.weyl1 -= ODD_PHI64; return s0 + s1; } /** * @require bytes.len > 0 **/ fn void Msws64Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_long, bytes); fn uint128 Msws64Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); fn uint Msws64Random.next_int(&self) : Random => (uint)self.next_long(); fn ushort Msws64Random.next_short(&self) : Random => (ushort)self.next_long(); fn char Msws64Random.next_byte(&self) : Random => (char)self.next_long(); // Msws32 struct Msws32Random { uint state0, state1; uint weyl0, weyl1; } fn void Msws32Random.set_seed(&self, char[] input) : Random { *self = bitcast(random::make_seed(uint[4], input), Msws32Random); } fn uint Msws32Random.next_int(&self) : Random { uint s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; self.state0 = self.state0.rotr(16); self.weyl0 += ODD_PHI32; self.state1 = self.state1 * self.state1 + self.weyl1; uint s1 = self.state1; self.state1 = self.state1.rotr(16); self.weyl1 -= ODD_PHI32; return s0 + s1; } /** * @require bytes.len > 0 **/ fn void Msws32Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int, bytes); fn uint128 Msws32Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); fn ulong Msws32Random.next_long(&self) : Random => @int_to_long(self.next_int()); fn ushort Msws32Random.next_short(&self) : Random => (ushort)self.next_int(); fn char Msws32Random.next_byte(&self) : Random => (char)self.next_int(); // Msws16 struct Msws16Random { ushort state0, state1; ushort weyl0, weyl1; } fn void Msws16Random.set_seed(&self, char[] input) : Random { *self = bitcast(random::make_seed(ushort[4], input), Msws16Random); } fn ushort Msws16Random.next_short(&self) : Random { ushort s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; self.state0 = self.state0.rotr(8); self.weyl0 += ODD_PHI16; self.state1 = self.state1 * self.state1 + self.weyl1; ushort s1 = self.state1; self.state1 = self.state1.rotr(8); self.weyl1 -= ODD_PHI16; return s0 + s1; } /** * @require bytes.len > 0 **/ fn void Msws16Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_short, bytes); fn uint128 Msws16Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); fn ulong Msws16Random.next_long(&self) : Random => @int_to_long(self.next_int()); fn uint Msws16Random.next_int(&self) : Random => @short_to_int(self.next_short()); fn char Msws16Random.next_byte(&self) : Random => (char)self.next_short(); // Msws8 struct Msws8Random { char state0, state1; char weyl0, weyl1; } fn void Msws8Random.set_seed(&self, char[] input) : Random { *self = bitcast(random::make_seed(char[4], input), Msws8Random); } fn char Msws8Random.next_byte(&self) : Random { char s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; self.state0 = self.state0.rotr(4); self.weyl0 += ODD_PHI8; self.state1 = self.state1 * self.state1 + self.weyl1; char s1 = self.state1; self.state1 = self.state1.rotr(4); self.weyl1 -= ODD_PHI8; return s0 + s1; } fn void Msws8Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_byte, bytes); fn uint128 Msws8Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); fn ulong Msws8Random.next_long(&self) : Random => @int_to_long(self.next_int()); fn uint Msws8Random.next_int(&self) : Random => @short_to_int(self.next_short()); fn ushort Msws8Random.next_short(&self) : Random => @char_to_short(self.next_byte());