mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
300 lines
6.2 KiB
C
300 lines
6.2 KiB
C
module std::math;
|
|
|
|
// 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
|
|
{
|
|
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)
|
|
{
|
|
self.random.fns = &MSWS_128_RANDOM_INTERFACE;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
// -------------------------------- 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)
|
|
{
|
|
self.random.fns = &MSWS_64_RANDOM_INTERFACE;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
// -------------------------------- 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)
|
|
{
|
|
self.random.fns = &MSWS_32_RANDOM_INTERFACE;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
// -------------------------------- 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)
|
|
{
|
|
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);
|
|
}
|
|
|
|
|
|
fn void Msws16RandomState.set_seed(&self, ushort[4] seed)
|
|
{
|
|
*self = bitcast(seed, Msws16RandomState);
|
|
}
|
|
|
|
fn ushort Msws16RandomState.next_short(&self)
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
// -------------------------------- 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)
|
|
{
|
|
self.random.fns = &MSWS_8_RANDOM_INTERFACE;
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|