mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
138 lines
2.8 KiB
C
138 lines
2.8 KiB
C
module std::math;
|
|
|
|
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 --------------------------------
|
|
|
|
struct Mcg128Random
|
|
{
|
|
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));
|
|
}
|
|
|
|
/**
|
|
* @require bytes.len > 0
|
|
**/
|
|
fn void Mcg128Random.next_bytes(&self, char[] bytes)
|
|
{
|
|
@random_value_to_bytes(self.state.next_long, bytes);
|
|
}
|
|
|
|
fn void Mcg128RandomState.set_seed(&self, uint128 seed)
|
|
{
|
|
*self = (Mcg128RandomState)seed | 1;
|
|
}
|
|
|
|
fn ulong Mcg128RandomState.next_long(&self)
|
|
{
|
|
uint128* s = (uint128*)self;
|
|
ulong result = (ulong)(*s >> 64);
|
|
*s *= MUL_MCG128;
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
// -------------------------------- Mcg64RandomState --------------------------------
|
|
|
|
struct Mcg64Random
|
|
{
|
|
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));
|
|
}
|
|
|
|
/**
|
|
* @require bytes.len > 0
|
|
**/
|
|
fn void Mcg64Random.next_bytes(&self, char[] bytes)
|
|
{
|
|
@random_value_to_bytes(self.state.next_int, bytes);
|
|
}
|
|
|
|
fn void Mcg64RandomState.set_seed(&self, ulong seed)
|
|
{
|
|
*self = (Mcg64RandomState)self | 1;
|
|
}
|
|
|
|
fn uint Mcg64RandomState.next_int(&self)
|
|
{
|
|
ulong* s = (ulong*)self;
|
|
uint result = (uint)(*s >> 32);
|
|
*s *= MUL_MCG64;
|
|
return result;
|
|
}
|
|
|
|
|
|
// -------------------------------- Mcg32RandomState --------------------------------
|
|
|
|
def Mcg32RandomState = distinct uint;
|
|
|
|
fn void Mcg32RandomState.set_seed(&self, uint seed)
|
|
{
|
|
*self = (Mcg32RandomState)seed | 1;
|
|
}
|
|
|
|
fn ushort Mcg32RandomState.next_short(&self)
|
|
{
|
|
uint* s = (uint*)self;
|
|
ushort result = (ushort)(*s >> 16);
|
|
*s *= MUL_MCG32;
|
|
return result;
|
|
}
|
|
|
|
|
|
// -------------------------------- Mcg16RandomState --------------------------------
|
|
|
|
def Mcg16RandomState = distinct ushort;
|
|
|
|
fn void Mcg16RandomState.set_seed(&self, ushort seed)
|
|
{
|
|
*self = (Mcg16RandomState)seed | 1;
|
|
}
|
|
|
|
fn char Mcg16RandomState.next_byte(&self)
|
|
{
|
|
ushort* s = (ushort*)self;
|
|
char result = (char)(*s >> 8);
|
|
*s *= MUL_MCG16;
|
|
return result;
|
|
}
|