mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
138 lines
2.3 KiB
C
138 lines
2.3 KiB
C
module std::math;
|
|
|
|
struct Random
|
|
{
|
|
RandomInterface* fns;
|
|
}
|
|
|
|
def RandomSeedFn = fn void(Random*, char[] seed);
|
|
def RandomNextBytesFn = fn void(Random*, char[] buffer);
|
|
|
|
struct RandomInterface
|
|
{
|
|
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);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
fn float Random.next_float(&self)
|
|
{
|
|
uint val = self.next_int() & (1 << 24 - 1);
|
|
return val / (float)(1 << 24);
|
|
}
|
|
|
|
fn double Random.next_double(&self)
|
|
{
|
|
ulong val = self.next_long() & (1UL << 53 - 1);
|
|
return val * 0x1.0p-53;
|
|
}
|
|
|
|
macro @random_value_to_bytes(#function, char[] bytes)
|
|
{
|
|
var $byte_size = $sizeof(#function());
|
|
usz len = bytes.len;
|
|
// Same size or smaller? Then just copy.
|
|
while (len > 0)
|
|
{
|
|
var value = #function();
|
|
if (len <= $byte_size)
|
|
{
|
|
bytes[..] = ((char*)&value)[:len];
|
|
return;
|
|
}
|
|
bytes[:$byte_size] = ((char*)&value)[:$byte_size];
|
|
len -= $byte_size;
|
|
bytes = bytes[$byte_size..];
|
|
}
|
|
unreachable();
|
|
} |