mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
- Order of attribute declaration is changed for `alias`. - Added `LANGUAGE_DEV_VERSION` env constant. - Rename `anyfault` -> `fault`. - Changed `fault` -> `faultdef`. - Added `attrdef` instead of `alias` for attribute aliases.
113 lines
3.7 KiB
Plaintext
113 lines
3.7 KiB
Plaintext
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 MUL_LCG128 @local = 0xdb36357734e34abb0050d0761fcdfc15;
|
|
const MUL_LCG64 @local = 0xd1342543de82ef95;
|
|
const MUL_LCG32 @local = 0x915f77f5;
|
|
const MUL_LCG16 @local = 0x915d; // TODO: Find good constant
|
|
|
|
|
|
// Lcg128_64
|
|
typedef Lcg128Random (Random) = uint128;
|
|
|
|
fn void Lcg128Random.set_seed(&self, char[] input) @dynamic
|
|
{
|
|
*self = (Lcg128Random)random::make_seed(uint128, input);
|
|
}
|
|
|
|
|
|
fn ulong Lcg128Random.next_long(&self) @dynamic
|
|
{
|
|
uint128* s = (uint128*)self;
|
|
ulong result = (ulong)(*s >> 64);
|
|
*s = *s * MUL_LCG128 + ODD_PHI128;
|
|
return result;
|
|
}
|
|
|
|
<*
|
|
@require bytes.len > 0
|
|
*>
|
|
fn void Lcg128Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_long, bytes);
|
|
fn uint128 Lcg128Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn uint Lcg128Random.next_int(&self) @dynamic => (uint)self.next_long();
|
|
fn ushort Lcg128Random.next_short(&self) @dynamic => (ushort)self.next_long();
|
|
fn char Lcg128Random.next_byte(&self) @dynamic => (char)self.next_long();
|
|
|
|
|
|
// -------------------------------- Lcg64_32 --------------------------------
|
|
typedef Lcg64Random (Random) = ulong;
|
|
|
|
fn void Lcg64Random.set_seed(&self, char[] seed) @dynamic
|
|
{
|
|
*self = (Lcg64Random)random::make_seed(ulong, seed);
|
|
}
|
|
|
|
|
|
fn uint Lcg64Random.next_int(&self) @dynamic
|
|
{
|
|
ulong* s = (ulong*)self;
|
|
uint result = (uint)(*s >> 32);
|
|
*s = *s * MUL_LCG64 + ODD_PHI64;
|
|
return result;
|
|
}
|
|
|
|
<*
|
|
@require bytes.len > 0
|
|
*>
|
|
fn void Lcg64Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_int, bytes);
|
|
fn uint128 Lcg64Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn ulong Lcg64Random.next_long(&self) @dynamic => @int_to_long(self.next_int());
|
|
fn ushort Lcg64Random.next_short(&self) @dynamic => (ushort)self.next_int();
|
|
fn char Lcg64Random.next_byte(&self) @dynamic => (char)self.next_int();
|
|
|
|
// -------------------------------- Lcg32_16 --------------------------------
|
|
|
|
typedef Lcg32Random (Random) = uint;
|
|
|
|
fn void Lcg32Random.set_seed(&self, char[] seed) @dynamic
|
|
{
|
|
*self = (Lcg32Random)random::make_seed(uint, seed);
|
|
}
|
|
|
|
fn ushort Lcg32Random.next_short(&self) @dynamic
|
|
{
|
|
uint* s = (uint*)self;
|
|
ushort result = (ushort)(*s >> 16);
|
|
*s = *s * MUL_LCG32 + ODD_PHI32;
|
|
return result;
|
|
}
|
|
|
|
fn void Lcg32Random.next_bytes(&self, char[] bytes) @dynamic => @random_value_to_bytes(self.next_short, bytes);
|
|
fn uint128 Lcg32Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn ulong Lcg32Random.next_long(&self) @dynamic => @int_to_long(self.next_int());
|
|
fn uint Lcg32Random.next_int(&self) @dynamic => @short_to_int(self.next_short());
|
|
fn char Lcg32Random.next_byte(&self) @dynamic => (char)self.next_short();
|
|
|
|
|
|
// -------------------------------- Lcg16_8 --------------------------------
|
|
typedef Lcg16Random (Random) = ushort;
|
|
|
|
fn void Lcg16Random.set_seed(&self, char[] seed) @dynamic
|
|
{
|
|
*self = (Lcg16Random)random::make_seed(ushort, seed);
|
|
}
|
|
|
|
fn char Lcg16Random.next_byte(&self) @dynamic
|
|
{
|
|
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) @dynamic => @random_value_to_bytes(self.next_byte, bytes);
|
|
fn uint128 Lcg16Random.next_int128(&self) @dynamic => @long_to_int128(self.next_long());
|
|
fn ulong Lcg16Random.next_long(&self) @dynamic => @int_to_long(self.next_int());
|
|
fn uint Lcg16Random.next_int(&self) @dynamic => @short_to_int(self.next_short());
|
|
fn ushort Lcg16Random.next_short(&self) @dynamic => @char_to_short(self.next_byte());
|