diff --git a/lib/std/math/math.random.c3 b/lib/std/math/math.random.c3 index 01468a0b3..69bf9fe68 100644 --- a/lib/std/math/math.random.c3 +++ b/lib/std/math/math.random.c3 @@ -1,95 +1,19 @@ -module std::math; +module std::math::random; -struct Random +protocol Random { - RandomInterface* fns; + fn void set_seed(&self, char[] input); + fn char next_byte(&self); + fn ushort next_short(&self); + fn uint next_int(&self); + fn ulong next_long(&self); + fn uint128 next_int128(&self); + fn void next_bytes(&self, char[] buffer); } -def RandomSeedFn = fn void(Random*, char[] seed); -def RandomNextBytesFn = fn void(Random*, char[] buffer); - -struct RandomInterface +macro Random.seed(&self, seed) { - RandomSeedFn seed_fn; - RandomNextBytesFn next_bytes_fn; -} - -/** - * @param [&inout] random - * @param [inout] buffer - **/ -fn void Random.next_bytes(&random, char[] buffer) -{ - if (!buffer.len) return; - random.fns.next_bytes_fn(random, buffer); -} - -/** - * @param [&inout] self - **/ -fn char Random.next_byte(&self) -{ - char result @noinit; - self.next_bytes(((char*)&result)[:1]); - return result; -} - -/** - * @param [&inout] self - **/ -fn ushort Random.next_short(&self) -{ - ushort result @noinit; - self.next_bytes(((char*)&result)[:2]); - return result; -} - -/** - * @param [&inout] self - **/ -fn uint Random.next_int(&self) -{ - uint result @noinit; - self.next_bytes(((char*)&result)[:4]); - return result; -} - -/** - * @param [&inout] self - **/ -fn ulong Random.next_long(&self) -{ - ulong result @noinit; - self.next_bytes(((char*)&result)[:8]); - return result; -} - -/** - * @param [&inout] self - **/ -fn uint128 Random.next_uint128(&self) -{ - uint128 result @noinit; - self.next_bytes(((char*)&result)[:16]); - return result; -} - -/** - * @param [&inout] self - * @require types::is_numerical($typeof(seed)) - **/ -macro void Random.seed_random(&self, seed) -{ - self.fns.seed_fn(self, @as_char_view(seed)) @inline; -} - -/** - * @param [&inout] random - * @param [in] seed - **/ -fn void Random.set_seed(&random, char[] seed) -{ - random.fns.seed_fn(random, seed); + self.set_seed(@as_char_view(seed)); } fn int Random.next(&random, int max) @@ -97,9 +21,6 @@ fn int Random.next(&random, int max) return (int)(random.next_double() * max); } -/** - * @param [&inout] self - **/ fn bool Random.next_bool(&self) { return self.next_byte() & 1 == 0; @@ -117,6 +38,11 @@ fn double Random.next_double(&self) return val * 0x1.0p-53; } +macro uint128 @long_to_int128(#function) => (uint128)#function << 64 + #function; +macro ulong @int_to_long(#function) => (ulong)#function << 32 + #function; +macro uint @short_to_int(#function) => (uint)#function << 16 + #function; +macro ushort @char_to_short(#function) => (ushort)#function << 8 + #function; + macro @random_value_to_bytes(#function, char[] bytes) { var $byte_size = $sizeof(#function()); diff --git a/lib/std/math/random/math.lcg.c3 b/lib/std/math/random/math.lcg.c3 index 5943d9809..399e079c0 100644 --- a/lib/std/math/random/math.lcg.c3 +++ b/lib/std/math/random/math.lcg.c3 @@ -1,4 +1,4 @@ -module std::math; +module std::math::random; // Move ODD_PHI into a shared module const ODD_PHI128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835; @@ -12,45 +12,16 @@ const MUL_LCG32 @local = 0x915f77f5; const MUL_LCG16 @local = 0x915d; // TODO: Find good constant -// -------------------------------- Lcg128_64 -------------------------------- +// Lcg128_64 +def Lcg128Random = distinct uint128; -struct Lcg128Random +fn void Lcg128Random.set_seed(&self, char[] input) : Random { - inline Random random; - Lcg128RandomState state; + *self = (Lcg128Random)random::make_seed(uint128, input); } -def Lcg128RandomState = distinct uint128; -const RandomInterface LCG_128_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Lcg128Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Lcg128Random.next_bytes, -}; - -fn void Lcg128Random.init(&self) -{ - self.random.fns = &LCG_128_RANDOM_INTERFACE; -} - -fn void Lcg128Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint128, input)); -} - -/** - * @require bytes.len > 0 - **/ -fn void Lcg128Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_long, bytes); -} - -fn void Lcg128RandomState.set_seed(&self, uint128 seed) @inline -{ - *self = (Lcg128RandomState)seed; -} - -fn ulong Lcg128RandomState.next_long(&self) +fn ulong Lcg128Random.next_long(&self) : Random { uint128* s = (uint128*)self; ulong result = (ulong)(*s >> 64); @@ -58,46 +29,26 @@ fn ulong Lcg128RandomState.next_long(&self) return result; } - -// -------------------------------- Lcg64_32 -------------------------------- - -struct Lcg64Random -{ - inline Random random; - Lcg64RandomState state; -} - -def Lcg64RandomState = distinct ulong; - -const RandomInterface LCG_64_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Lcg64Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Lcg64Random.next_bytes, -}; - -fn void Lcg64Random.init(&self) -{ - self.random.fns = &LCG_64_RANDOM_INTERFACE; -} - -fn void Lcg64Random.set_seed(&self, char[] seed) -{ - self.state.set_seed(random::make_seed(ulong, seed)); -} - /** * @require bytes.len > 0 **/ -fn void Lcg64Random.next_bytes(&self, char[] bytes) +fn void Lcg128Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_long, bytes); +fn uint128 Lcg128Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn uint Lcg128Random.next_int(&self) : Random => (uint)self.next_long(); +fn ushort Lcg128Random.next_short(&self) : Random => (ushort)self.next_long(); +fn char Lcg128Random.next_byte(&self) : Random => (char)self.next_long(); + + +// -------------------------------- Lcg64_32 -------------------------------- +def Lcg64Random = distinct ulong; + +fn void Lcg64Random.set_seed(&self, char[] seed) : Random { - @random_value_to_bytes(self.state.next_int, bytes); + *self = (Lcg64Random)random::make_seed(ulong, seed); } -fn void Lcg64RandomState.set_seed(&self, ulong seed) -{ - *self = (Lcg64RandomState)seed; -} -fn uint Lcg64RandomState.next_int(&self) +fn uint Lcg64Random.next_int(&self) : Random { ulong* s = (ulong*)self; uint result = (uint)(*s >> 32); @@ -105,17 +56,25 @@ fn uint Lcg64RandomState.next_int(&self) return result; } +/** + * @require bytes.len > 0 + **/ +fn void Lcg64Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int, bytes); +fn uint128 Lcg64Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Lcg64Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn ushort Lcg64Random.next_short(&self) : Random => (ushort)self.next_int(); +fn char Lcg64Random.next_byte(&self) : Random => (char)self.next_int(); // -------------------------------- Lcg32_16 -------------------------------- -def Lcg32RandomState = distinct uint; +def Lcg32Random = distinct uint; -fn void Lcg32RandomState.set_seed(&self, uint seed) +fn void Lcg32Random.set_seed(&self, char[] seed) : Random { - *self = (Lcg32RandomState)seed; + *self = (Lcg32Random)random::make_seed(uint, seed); } -fn ushort Lcg32RandomState.next_short(&self) +fn ushort Lcg32Random.next_short(&self) : Random { uint* s = (uint*)self; ushort result = (ushort)(*s >> 16); @@ -123,20 +82,31 @@ fn ushort Lcg32RandomState.next_short(&self) return result; } +fn void Lcg32Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_short, bytes); +fn uint128 Lcg32Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Lcg32Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Lcg32Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn char Lcg32Random.next_byte(&self) : Random => (char)self.next_short(); + // -------------------------------- Lcg16_8 -------------------------------- +def Lcg16Random = distinct ushort; -def Lcg16RandomState = distinct ushort; - -fn void Lcg16RandomState.set_seed(&self, ushort seed) +fn void Lcg16Random.set_seed(&self, char[] seed) : Random { - *self = (Lcg16RandomState)seed; + *self = (Lcg16Random)random::make_seed(ushort, seed); } -fn char Lcg16RandomState.next_byte(&self) +fn char Lcg16Random.next_byte(&self) : Random { ushort* s = (ushort*)self; char result = (char)(*s >> 8); *s = *s * MUL_LCG16 + ODD_PHI16; return result; } + +fn void Lcg16Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_byte, bytes); +fn uint128 Lcg16Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Lcg16Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Lcg16Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn ushort Lcg16Random.next_short(&self) : Random => @char_to_short(self.next_byte()); diff --git a/lib/std/math/random/math.mcg.c3 b/lib/std/math/random/math.mcg.c3 index d72ff8e22..764a6eeb8 100644 --- a/lib/std/math/random/math.mcg.c3 +++ b/lib/std/math/random/math.mcg.c3 @@ -1,49 +1,28 @@ -module std::math; +module std::math::random; const MUL_MCG128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835; const MUL_MCG64 @local = 0xf1357aea2e62a9c5; const MUL_MCG32 @local = 0x93d765dd; const MUL_MCG16 @local = 0x93d5; // TODO: Find good constant -// -------------------------------- Mcg128_64 -------------------------------- +// Mcg128_64 -struct Mcg128Random +def Mcg128Random = distinct uint128; + +fn void Mcg128Random.set_seed(&self, char[] seed) : Random { - inline Random random; - Mcg128RandomState state; -} - -def Mcg128RandomState = distinct uint128; - -const RandomInterface MCG_128_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Mcg128Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Mcg128Random.next_bytes, -}; - -fn void Mcg128Random.init(&self) -{ - self.random.fns = &MCG_64_RANDOM_INTERFACE; -} - -fn void Mcg128Random.set_seed(&self, char[] seed) -{ - self.state.set_seed(random::make_seed(uint128, seed)); + *self = (Mcg128Random)(random::make_seed(uint128, seed) | 1); } /** * @require bytes.len > 0 **/ -fn void Mcg128Random.next_bytes(&self, char[] bytes) +fn void Mcg128Random.next_bytes(&self, char[] bytes) : Random { - @random_value_to_bytes(self.state.next_long, bytes); + @random_value_to_bytes(self.next_long, bytes); } -fn void Mcg128RandomState.set_seed(&self, uint128 seed) -{ - *self = (Mcg128RandomState)seed | 1; -} - -fn ulong Mcg128RandomState.next_long(&self) +fn ulong Mcg128Random.next_long(&self) : Random { uint128* s = (uint128*)self; ulong result = (ulong)(*s >> 64); @@ -51,48 +30,32 @@ fn ulong Mcg128RandomState.next_long(&self) return result; } +fn uint128 Mcg128Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn uint Mcg128Random.next_int(&self) : Random => (uint)self.next_long(); +fn ushort Mcg128Random.next_short(&self) : Random => (ushort)self.next_long(); +fn char Mcg128Random.next_byte(&self) : Random => (char)self.next_long(); -// -------------------------------- Mcg64RandomState -------------------------------- -struct Mcg64Random +// Mcg64RandomState + +def Mcg64Random = distinct ulong; + +fn void Mcg64Random.set_seed(&self, char[] seed) : Random { - inline Random random; - Mcg64RandomState state; -} - -const RandomInterface MCG_64_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Mcg64Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Mcg64Random.next_bytes, -}; - -def Mcg64RandomState = distinct ulong; - -fn void Mcg64Random.init(&self) -{ - self.random.fns = &MCG_64_RANDOM_INTERFACE; -} - -fn void Mcg64Random.set_seed(&self, char[] seed) -{ - self.state.set_seed(random::make_seed(ulong, seed)); + *self = (Mcg64Random)random::make_seed(ulong, seed) | 1; } /** * @require bytes.len > 0 **/ -fn void Mcg64Random.next_bytes(&self, char[] bytes) +fn void Mcg64Random.next_bytes(&self, char[] bytes) : Random { - @random_value_to_bytes(self.state.next_int, bytes); + @random_value_to_bytes(self.next_int, bytes); } -fn void Mcg64RandomState.set_seed(&self, ulong seed) -{ - *self = (Mcg64RandomState)self | 1; -} - -fn uint Mcg64RandomState.next_int(&self) +fn uint Mcg64Random.next_int(&self) : Random { ulong* s = (ulong*)self; uint result = (uint)(*s >> 32); @@ -100,17 +63,22 @@ fn uint Mcg64RandomState.next_int(&self) return result; } +fn uint128 Mcg64Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Mcg64Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn ushort Mcg64Random.next_short(&self) : Random => (ushort)self.next_int(); +fn char Mcg64Random.next_byte(&self) : Random => (char)self.next_int(); -// -------------------------------- Mcg32RandomState -------------------------------- -def Mcg32RandomState = distinct uint; +// Mcg32Random -fn void Mcg32RandomState.set_seed(&self, uint seed) +def Mcg32Random = distinct uint; + +fn void Mcg32Random.set_seed(&self, char[] seed) : Random { - *self = (Mcg32RandomState)seed | 1; + *self = (Mcg32Random)random::make_seed(uint, seed) | 1; } -fn ushort Mcg32RandomState.next_short(&self) +fn ushort Mcg32Random.next_short(&self) { uint* s = (uint*)self; ushort result = (ushort)(*s >> 16); @@ -118,20 +86,34 @@ fn ushort Mcg32RandomState.next_short(&self) return result; } +/** + * @require bytes.len > 0 + **/ +fn void Mcg32Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_short, bytes); +fn uint128 Mcg32Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Mcg32Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Mcg32Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn char Mcg32Random.next_byte(&self) : Random => (char)self.next_short(); // -------------------------------- Mcg16RandomState -------------------------------- -def Mcg16RandomState = distinct ushort; +def Mcg16Random = distinct ushort; -fn void Mcg16RandomState.set_seed(&self, ushort seed) +fn void Mcg16Random.set_seed(&self, char[] seed) : Random { - *self = (Mcg16RandomState)seed | 1; + *self = (Mcg16Random)random::make_seed(ushort, seed) | 1; } -fn char Mcg16RandomState.next_byte(&self) +fn char Mcg16Random.next_byte(&self) : Random { ushort* s = (ushort*)self; char result = (char)(*s >> 8); *s *= MUL_MCG16; return result; } + +fn void Mcg16Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_byte, bytes); +fn uint128 Mcg16Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Mcg16Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Mcg16Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn ushort Mcg16Random.next_short(&self) : Random => @char_to_short(self.next_byte()); diff --git a/lib/std/math/random/math.msws.c3 b/lib/std/math/random/math.msws.c3 index b57ad3dd2..3cdb91a9b 100644 --- a/lib/std/math/random/math.msws.c3 +++ b/lib/std/math/random/math.msws.c3 @@ -1,4 +1,4 @@ -module std::math; +module std::math::random; // Move ODD_PHI into a shared module const ODD_PHI128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835; @@ -7,50 +7,20 @@ const ODD_PHI32 @local = 0x9e3779b9; const ODD_PHI16 @local = 0x9e37; const ODD_PHI8 @local = 0x9f; - -// -------------------------------- Msws128 -------------------------------- - +// Msws128 struct Msws128Random -{ - inline Random random; - Msws128RandomState state; -} - -struct Msws128RandomState { uint128 state0, state1; uint128 weyl0, weyl1; } -const RandomInterface MSWS_128_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Msws128Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Msws128Random.next_bytes, -}; - -fn void Msws128Random.init(&self) +fn void Msws128Random.set_seed(&self, char[] input) : Random { - self.random.fns = &MSWS_128_RANDOM_INTERFACE; + *self = bitcast(random::make_seed(uint128[4], input), Msws128Random); } -fn void Msws128Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint128[4], input)); -} -/** - * @require bytes.len > 0 - **/ -fn void Msws128Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_int128, bytes); -} - -fn void Msws128RandomState.set_seed(&self, uint128[4] seed) -{ - *self = bitcast(seed, Msws128RandomState); -} - -fn uint128 Msws128RandomState.next_int128(&self) +fn uint128 Msws128Random.next_int128(&self) { uint128 s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; @@ -65,50 +35,29 @@ fn uint128 Msws128RandomState.next_int128(&self) 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 -------------------------------- +// Msws64 struct Msws64Random -{ - inline Random random; - Msws64RandomState state; -} - -struct Msws64RandomState { ulong state0, state1; ulong weyl0, weyl1; } -const RandomInterface MSWS_64_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Msws64Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Msws64Random.next_bytes, -}; - -fn void Msws64Random.init(&self) +fn void Msws64Random.set_seed(&self, char[] input) : Random { - self.random.fns = &MSWS_64_RANDOM_INTERFACE; + *self = bitcast(random::make_seed(ulong[4], input), Msws64Random); } -fn void Msws64Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(ulong[4], input)); -} - -/** - * @require bytes.len > 0 - **/ -fn void Msws64Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_long, bytes); -} - -fn void Msws64RandomState.set_seed(&self, ulong[4] seed) -{ - *self = bitcast(seed, Msws64RandomState); -} - -fn ulong Msws64RandomState.next_long(&self) +fn ulong Msws64Random.next_long(&self) : Random { ulong s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; @@ -123,50 +72,29 @@ fn ulong Msws64RandomState.next_long(&self) 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 -------------------------------- - +// Msws32 struct Msws32Random -{ - inline Random random; - Msws32RandomState state; -} - -struct Msws32RandomState { uint state0, state1; uint weyl0, weyl1; } -const RandomInterface MSWS_32_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Msws32Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Msws32Random.next_bytes, -}; - -fn void Msws32Random.init(&self) +fn void Msws32Random.set_seed(&self, char[] input) : Random { - self.random.fns = &MSWS_32_RANDOM_INTERFACE; + *self = bitcast(random::make_seed(uint[4], input), Msws32Random); } -fn void Msws32Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint[4], input)); -} -/** - * @require bytes.len > 0 - **/ -fn void Msws32Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_int, bytes); -} - -fn void Msws32RandomState.set_seed(&self, uint[4] seed) -{ - *self = bitcast(seed, Msws32RandomState); -} - -fn uint Msws32RandomState.next_int(&self) +fn uint Msws32Random.next_int(&self) : Random { uint s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; @@ -181,51 +109,30 @@ fn uint Msws32RandomState.next_int(&self) 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 -------------------------------- +// Msws16 struct Msws16Random -{ - inline Random random; - Msws16RandomState state; -} - -struct Msws16RandomState { ushort state0, state1; ushort weyl0, weyl1; } -const RandomInterface MSWS_16_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Msws16Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Msws16Random.next_bytes, -}; - -fn void Msws16Random.init(&self) +fn void Msws16Random.set_seed(&self, char[] input) : Random { - self.random.fns = &MSWS_16_RANDOM_INTERFACE; -} - -fn void Msws16Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(ushort[4], input)); -} - -/** - * @require bytes.len > 0 - **/ -fn void Msws16Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_short, bytes); + *self = bitcast(random::make_seed(ushort[4], input), Msws16Random); } -fn void Msws16RandomState.set_seed(&self, ushort[4] seed) -{ - *self = bitcast(seed, Msws16RandomState); -} - -fn ushort Msws16RandomState.next_short(&self) +fn ushort Msws16Random.next_short(&self) : Random { ushort s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; @@ -240,50 +147,28 @@ fn ushort Msws16RandomState.next_short(&self) 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 -------------------------------- - +// Msws8 struct Msws8Random -{ - inline Random random; - Msws8RandomState state; -} - -struct Msws8RandomState { char state0, state1; char weyl0, weyl1; } -const RandomInterface MSWS_8_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Msws8Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Msws8Random.next_bytes, -}; - -fn void Msws8Random.init(&self) +fn void Msws8Random.set_seed(&self, char[] input) : Random { - self.random.fns = &MSWS_8_RANDOM_INTERFACE; + *self = bitcast(random::make_seed(char[4], input), Msws8Random); } -fn void Msws8Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(char[4], input)); -} - -/** - * @require bytes.len > 0 - **/ -fn void Msws8Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_byte, bytes); -} - -fn void Msws8RandomState.set_seed(&msws, char[4] seed) -{ - *msws = bitcast(seed, Msws8RandomState); -} - -fn char Msws8RandomState.next_byte(&self) +fn char Msws8Random.next_byte(&self) : Random { char s0 = self.state0; self.state0 = self.state0 * self.state0 + self.weyl0; @@ -297,3 +182,9 @@ fn char Msws8RandomState.next_byte(&self) 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()); diff --git a/lib/std/math/random/math.pcg.c3 b/lib/std/math/random/math.pcg.c3 index b981f6ff7..1cf3226fa 100644 --- a/lib/std/math/random/math.pcg.c3 +++ b/lib/std/math/random/math.pcg.c3 @@ -1,4 +1,4 @@ -module std::math; +module std::math::random; // Move ODD_PHI into a shared module const ODD_PHI128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835; @@ -14,43 +14,16 @@ const MUL_LCG16 @local = 0x915d; // TODO: Find good constant // -------------------------------- Pcg128_64 -------------------------------- -struct Pcg128Random + +def Pcg128Random = distinct uint128; + +fn void Pcg128Random.set_seed(&self, char[] input) : Random { - inline Random random; - Pcg128RandomState state; + *self = (Pcg128Random)random::make_seed(uint128, input); } -def Pcg128RandomState = distinct uint128; -const RandomInterface PCG_128_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Pcg128Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Pcg128Random.next_bytes, -}; - -fn void Pcg128Random.init(&self) -{ - self.random.fns = &PCG_128_RANDOM_INTERFACE; -} - -fn void Pcg128Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint128, input)); -} - -/** - * @require bytes.len > 0 - **/ -fn void Pcg128Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_long, bytes); -} - -fn void Pcg128RandomState.set_seed(&self, uint128 seed) -{ - *self = (Pcg128RandomState)seed; -} - -fn ulong Pcg128RandomState.next_long(&self) +fn ulong Pcg128Random.next_long(&self) { const ROT_SHIFT = 64 - 6; uint128* s = (uint128*)self; @@ -60,46 +33,25 @@ fn ulong Pcg128RandomState.next_long(&self) return ((ulong)(xor >> ROT_SHIFT)).rotr(rot); } - -// -------------------------------- Pcg64_32 -------------------------------- - -struct Pcg64Random -{ - inline Random random; - Pcg64RandomState state; -} - -def Pcg64RandomState = distinct ulong; - -const RandomInterface PCG_64_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Pcg64Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Pcg64Random.next_bytes, -}; - -fn void Pcg64Random.init(&self) -{ - self.random.fns = &PCG_64_RANDOM_INTERFACE; -} - -fn void Pcg64Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(ulong, input)); -} - /** * @require bytes.len > 0 **/ -fn void Pcg64Random.next_bytes(&self, char[] bytes) +fn void Pcg128Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_long, bytes); +fn uint128 Pcg128Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn uint Pcg128Random.next_int(&self) : Random => (uint)self.next_long(); +fn ushort Pcg128Random.next_short(&self) : Random => (ushort)self.next_long(); +fn char Pcg128Random.next_byte(&self) : Random => (char)self.next_long(); + +// -------------------------------- Pcg64_32 -------------------------------- + +def Pcg64Random = distinct ulong; + +fn void Pcg64Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_int, bytes); + *self = (Pcg64Random)random::make_seed(ulong, input); } -fn void Pcg64RandomState.set_seed(&self, ulong seed) -{ - *self = (Pcg64RandomState)seed; -} - -fn uint Pcg64RandomState.next_int(&self) +fn uint Pcg64Random.next_int(&self) : Random { const ROT_SHIFT = 32 - 5; ulong* s = (ulong*)self; @@ -109,46 +61,26 @@ fn uint Pcg64RandomState.next_int(&self) return ((uint)(xor >> ROT_SHIFT)).rotr(rot); } - -// -------------------------------- Pcg32_16 -------------------------------- - -struct Pcg32Random -{ - inline Random random; - Pcg32RandomState state; -} - -def Pcg32RandomState = distinct uint; - -const RandomInterface PCG_32_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Pcg32Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Pcg32Random.next_bytes, -}; - -fn void Pcg32Random.init(&self) -{ - self.random.fns = &PCG_32_RANDOM_INTERFACE; -} - -fn void Pcg32Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint, input)); -} - /** * @require bytes.len > 0 **/ -fn void Pcg32Random.next_bytes(&self, char[] bytes) +fn void Pcg64Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int, bytes); +fn uint128 Pcg64Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Pcg64Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn ushort Pcg64Random.next_short(&self) : Random => (ushort)self.next_int(); +fn char Pcg64Random.next_byte(&self) : Random => (char)self.next_int(); + + +// -------------------------------- Pcg32_16 -------------------------------- + +def Pcg32Random = distinct uint; + +fn void Pcg32Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_short, bytes); + *self = (Pcg32Random)random::make_seed(uint, input); } -fn void Pcg32RandomState.set_seed(&self, uint seed) -{ - *self = (Pcg32RandomState)seed; -} - -fn ushort Pcg32RandomState.next_short(&self) +fn ushort Pcg32Random.next_short(&self) : Random { const ROT_SHIFT = 16 - 4; uint* s = (uint*)self; @@ -158,46 +90,25 @@ fn ushort Pcg32RandomState.next_short(&self) return ((ushort)(xor >> ROT_SHIFT)).rotr(rot); } - -// -------------------------------- Pcg16_8 -------------------------------- - -struct Pcg16Random -{ - inline Random random; - Pcg16RandomState state; -} - -def Pcg16RandomState = distinct ushort; - -const RandomInterface PCG_16_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Pcg16Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Pcg16Random.next_bytes, -}; - -fn void Pcg16Random.init(&self) -{ - self.random.fns = &PCG_16_RANDOM_INTERFACE; -} - -fn void Pcg16Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(ushort, input)); -} - /** * @require bytes.len > 0 **/ -fn void Pcg16Random.next_bytes(&self, char[] bytes) +fn void Pcg32Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_short, bytes); +fn uint128 Pcg32Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Pcg32Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Pcg32Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn char Pcg32Random.next_byte(&self) : Random => (char)self.next_short(); + +// -------------------------------- Pcg16_8 -------------------------------- + +def Pcg16Random = distinct ushort; + +fn void Pcg16Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_byte, bytes); + *self = (Pcg16Random)random::make_seed(ushort, input); } -fn void Pcg16RandomState.set_seed(&self, ushort seed) -{ - *self = (Pcg16RandomState)seed; -} - -fn char Pcg16RandomState.next_byte(&self) +fn char Pcg16Random.next_byte(&self) : Random { const ROT_SHIFT = 8 - 3; ushort* s = (ushort*)self; @@ -206,3 +117,9 @@ fn char Pcg16RandomState.next_byte(&self) *s = *s * MUL_LCG16 + ODD_PHI16; return ((char)(xor >> ROT_SHIFT)).rotr(rot); } + +fn void Pcg16Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_byte, bytes); +fn uint128 Pcg16Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Pcg16Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Pcg16Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn ushort Pcg16Random.next_short(&self) : Random => @char_to_short(self.next_byte()); diff --git a/lib/std/math/random/math.sfc.c3 b/lib/std/math/random/math.sfc.c3 index 4d78d3182..2b3bb84d9 100644 --- a/lib/std/math/random/math.sfc.c3 +++ b/lib/std/math/random/math.sfc.c3 @@ -1,4 +1,4 @@ -module std::math; +module std::math::random; // Move ODD_PHI into a shared module const ODD_PHI128 @local = 0x9e3779b97f4a7c15f39cc0605cedc835; @@ -8,46 +8,16 @@ const ODD_PHI16 @local = 0x9e37; const ODD_PHI8 @local = 0x9f; -// -------------------------------- Sfc128 -------------------------------- +// Sfc128 -struct Sfc128Random +def Sfc128Random = distinct uint128[4]; + +fn void Sfc128Random.set_seed(&self, char[] input) : Random { - inline Random random; - Sfc128RandomState state; + *self = (Sfc128Random)random::make_seed(uint128[4], input); } -def Sfc128RandomState = distinct uint128[4]; - - -const RandomInterface SFC_128_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Sfc128Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Sfc128Random.next_bytes, -}; - -fn void Sfc128Random.init(&self) -{ - self.random.fns = &SFC_128_RANDOM_INTERFACE; -} - -fn void Sfc128Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint128[4], input)); -} - -/** - * @require bytes.len > 0 - **/ -fn void Sfc128Random.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_int128, bytes); -} - -fn void Sfc128RandomState.set_seed(&self, uint128[4] seed) -{ - *self = (Sfc128RandomState)seed; -} - -fn uint128 Sfc128RandomState.next_int128(&self) // TODO: Find good constant +fn uint128 Sfc128Random.next_int128(&self) : Random // TODO: Find good constant { uint128* s = (uint128[4]*)self; uint128 result = s[0] + s[1] + s[3]; @@ -58,47 +28,26 @@ fn uint128 Sfc128RandomState.next_int128(&self) // TODO: Find good constant return result; } - -// -------------------------------- Sfc64 -------------------------------- - - -struct Sfc64Random -{ - inline Random random; - Sfc64RandomState state; -} - -def Sfc64RandomState = distinct ulong[4]; - -const RandomInterface SFC_64_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Sfc64Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Sfc64Random.next_bytes, -}; - -fn void Sfc64Random.init(&self) -{ - self.random.fns = &SFC_64_RANDOM_INTERFACE; -} - -fn void Sfc64Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(ulong[4], input)); -} - /** * @require bytes.len > 0 **/ -fn void Sfc64Random.next_bytes(&self, char[] bytes) +fn void Sfc128Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int128, bytes); +fn ulong Sfc128Random.next_long(&self) : Random => (uint)self.next_int128(); +fn uint Sfc128Random.next_int(&self) : Random => (uint)self.next_int128(); +fn ushort Sfc128Random.next_short(&self) : Random => (ushort)self.next_int128(); +fn char Sfc128Random.next_byte(&self) : Random => (char)self.next_int128(); + + +// -------------------------------- Sfc64 -------------------------------- + +def Sfc64Random = distinct ulong[4]; + +fn void Sfc64Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_long, bytes); + *self = (Sfc64Random)random::make_seed(ulong[4], input); } -fn void Sfc64RandomState.set_seed(&self, ulong[4] seed) -{ - *self = (Sfc64RandomState)seed; -} - -fn ulong Sfc64RandomState.next_long(&self) +fn ulong Sfc64Random.next_long(&self) : Random { ulong* s = (ulong[4]*)self; ulong result = s[0] + s[1] + s[3]; @@ -109,47 +58,25 @@ fn ulong Sfc64RandomState.next_long(&self) return result; } - -// -------------------------------- Sfc32 -------------------------------- - - -struct Sfc32Random -{ - inline Random random; - Sfc32RandomState state; -} - -def Sfc32RandomState = distinct uint[4]; - -const RandomInterface SFC_32_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Sfc32Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Sfc32Random.next_bytes, -}; - -fn void Sfc32Random.init(&self) -{ - self.random.fns = &SFC_32_RANDOM_INTERFACE; -} - -fn void Sfc32Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(uint[4], input)); -} - /** * @require bytes.len > 0 **/ -fn void Sfc32Random.next_bytes(&self, char[] bytes) +fn void Sfc64Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_long, bytes); +fn uint128 Sfc64Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn uint Sfc64Random.next_int(&self) : Random => (uint)self.next_long(); +fn ushort Sfc64Random.next_short(&self) : Random => (ushort)self.next_long(); +fn char Sfc64Random.next_byte(&self) : Random => (char)self.next_long(); + +// -------------------------------- Sfc32 -------------------------------- + +def Sfc32Random = distinct uint[4]; + +fn void Sfc32Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_int, bytes); + *self = (Sfc32Random)random::make_seed(uint[4], input); } -fn void Sfc32RandomState.set_seed(&self, uint[4] seed) -{ - *self = (Sfc32RandomState)seed; -} - -fn uint Sfc32RandomState.next_int(&sfc) +fn uint Sfc32Random.next_int(&sfc) : Random { uint* s = (uint[4]*)sfc; uint result = s[0] + s[1] + s[3]; @@ -160,46 +87,26 @@ fn uint Sfc32RandomState.next_int(&sfc) return result; } - -// -------------------------------- Sfc16 -------------------------------- - -struct Sfc16Random -{ - inline Random random; - Sfc16RandomState state; -} - -def Sfc16RandomState = distinct ushort[4]; - -const RandomInterface SFC_16_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Sfc16Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Sfc16Random.next_bytes, -}; - -fn void Sfc16Random.init(&self) -{ - self.random.fns = &SFC_16_RANDOM_INTERFACE; -} - -fn void Sfc16Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(ushort[4], input)); -} - /** * @require bytes.len > 0 **/ -fn void Sfc16Random.next_bytes(&self, char[] bytes) +fn void Sfc32Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int, bytes); +fn uint128 Sfc32Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Sfc32Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn ushort Sfc32Random.next_short(&self) : Random => (ushort)self.next_int(); +fn char Sfc32Random.next_byte(&self) : Random => (char)self.next_int(); + +// -------------------------------- Sfc16 -------------------------------- + +def Sfc16Random = distinct ushort[4]; + +fn void Sfc16Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_short, bytes); + *self = (Sfc16Random)random::make_seed(ushort[4], input); } -fn void Sfc16RandomState.set_seed(&self, ushort[4] seed) -{ - *self = (Sfc16RandomState)seed; -} -fn ushort Sfc16RandomState.next_short(&seed) +fn ushort Sfc16Random.next_short(&seed) : Random { ushort* s = (ushort[4]*)seed; ushort result = s[0] + s[1] + s[3]; @@ -210,46 +117,26 @@ fn ushort Sfc16RandomState.next_short(&seed) return result; } - -// -------------------------------- Sfc8 -------------------------------- - -struct Sfc8Random -{ - inline Random random; - Sfc8RandomState state; -} - -def Sfc8RandomState = distinct char[4]; - -const RandomInterface SFC_8_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&Sfc8Random.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&Sfc8Random.next_bytes, -}; - -fn void Sfc8Random.init(&self) -{ - self.random.fns = &SFC_8_RANDOM_INTERFACE; -} - -fn void Sfc8Random.set_seed(&self, char[] input) -{ - self.state.set_seed(random::make_seed(char[4], input)); -} - /** * @require bytes.len > 0 **/ -fn void Sfc8Random.next_bytes(&self, char[] bytes) +fn void Sfc16Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_short, bytes); +fn uint128 Sfc16Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Sfc16Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Sfc16Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn char Sfc16Random.next_byte(&self) : Random => (char)self.next_short(); + +// -------------------------------- Sfc8 -------------------------------- + + +def Sfc8Random = distinct char[4]; + +fn void Sfc8Random.set_seed(&self, char[] input) : Random { - @random_value_to_bytes(self.state.next_byte, bytes); + *self = (Sfc8Random)random::make_seed(char[4], input); } -fn void Sfc8RandomState.set_seed(&self, char[4] seed) -{ - *self = (Sfc8RandomState)seed; -} - -fn char Sfc8RandomState.next_byte(&self) // TODO: Find better constants +fn char Sfc8Random.next_byte(&self) : Random // TODO: Find better constants { char* s = (char[4]*)self; char result = s[0] + s[1] + s[3]; @@ -259,3 +146,9 @@ fn char Sfc8RandomState.next_byte(&self) // TODO: Find better constants s[3] += ODD_PHI8; return result; } + +fn void Sfc8Random.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_byte, bytes); +fn uint128 Sfc8Random.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong Sfc8Random.next_long(&self) : Random => @int_to_long(self.next_int()); +fn uint Sfc8Random.next_int(&self) : Random => @short_to_int(self.next_short()); +fn ushort Sfc8Random.next_short(&self) : Random => @char_to_short(self.next_byte()); \ No newline at end of file diff --git a/lib/std/math/random/math.simple_random.c3 b/lib/std/math/random/math.simple_random.c3 index 99eaf1a85..2bf48a542 100644 --- a/lib/std/math/random/math.simple_random.c3 +++ b/lib/std/math/random/math.simple_random.c3 @@ -1,53 +1,34 @@ -module std::math; +module std::math::random; -struct SimpleRandom -{ - inline Random random; - SimpleRandomState state; -} +def SimpleRandom = distinct ulong; -def SimpleRandomState = distinct ulong; -const RandomInterface SIMPLE_RANDOM_INTERFACE @local = { - .seed_fn = (RandomSeedFn)&SimpleRandom.set_seed, - .next_bytes_fn = (RandomNextBytesFn)&SimpleRandom.next_bytes, -}; - -fn void SimpleRandom.init(&self) -{ - self.random.fns = &SIMPLE_RANDOM_INTERFACE; -} - -/** - * @require bytes.len > 0 - **/ -fn void SimpleRandom.next_bytes(&self, char[] bytes) -{ - @random_value_to_bytes(self.state.next_int, bytes); -} - -fn void SimpleRandom.set_seed(&self, char[] seed) +fn void SimpleRandom.set_seed(&self, char[] seed) : Random { char[8] full; foreach (i, c : seed) { full[i % 8] ^= c; } - self.state.set_seed(bitcast(full, ulong)); + *self = (SimpleRandom)(bitcast(full, ulong) ^ SIMPLE_RANDOM_MULTIPLIER) & SIMPLE_RANDOM_MASK; } -fn void SimpleRandomState.set_seed(&self, ulong seed) -{ - *self = (SimpleRandomState)(seed ^ SIMPLE_RANDOM_MULTIPLIER) & SIMPLE_RANDOM_MASK; -} - -fn uint SimpleRandomState.next_int(&self) +fn uint SimpleRandom.next_int(&self) : Random { ulong nextseed = ((ulong)*self * SIMPLE_RANDOM_MULTIPLIER + SIMPLE_RANDOM_ADDEND) & SIMPLE_RANDOM_MASK; - *self = (SimpleRandomState)nextseed; + *self = (SimpleRandom)nextseed; return (uint)(nextseed >> (48 - 32)); } +/** + * @require bytes.len > 0 + **/ +fn void SimpleRandom.next_bytes(&self, char[] bytes) : Random => @random_value_to_bytes(self.next_int, bytes); +fn uint128 SimpleRandom.next_int128(&self) : Random => @long_to_int128(self.next_long()); +fn ulong SimpleRandom.next_long(&self) : Random => @int_to_long(self.next_int()); +fn ushort SimpleRandom.next_short(&self) : Random => (ushort)self.next_int(); +fn char SimpleRandom.next_byte(&self) : Random => (char)self.next_int(); + const long SIMPLE_RANDOM_MULTIPLIER @local = 0x5DEECE66D; const long SIMPLE_RANDOM_ADDEND @local = 0xB; const long SIMPLE_RANDOM_MASK @local = (1u64 << 48) - 1; diff --git a/src/version.h b/src/version.h index b495e73a0..c7a06d668 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.670" \ No newline at end of file +#define COMPILER_VERSION "0.4.671" \ No newline at end of file