Files
c3c/lib/std/math/random/math.pcg.c3
Pierre Curto fd5336c56e lib/std/io/stream: add LimitReader (#858)
* lib/std/io/stream: add LimitReader

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>

* lib/std: more method conversions to use new receiver notation

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>

---------

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2023-07-17 20:22:29 +02:00

93 lines
2.3 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 MUL_LCG128 @local = 0xdb36357734e34abb0050d0761fcdfc15;
const MUL_LCG64 @local = 0xd1342543de82ef95;
const MUL_LCG32 @local = 0x915f77f5;
const MUL_LCG16 @local = 0x915d; // TODO: Find good constant
// -------------------------------- Pcg128_64 --------------------------------
def Pcg128_64 = distinct uint128;
fn void Pcg128_64.seed(&pcg, char[16] seed)
{
*pcg = bitcast(seed, Pcg128_64);
}
fn ulong Pcg128_64.next(&pcg)
{
const ROT_SHIFT = 64 - 6;
uint128* s = (uint128*)pcg;
uint128 xor = *s ^ *s >> ((128 - ROT_SHIFT) / 2);
char rot = (char)(*s >> (128 - 6));
*s = *s * MUL_LCG128 + ODD_PHI128;
return ((ulong)(xor >> ROT_SHIFT)).rotr(rot);
}
// -------------------------------- Pcg64_32 --------------------------------
def Pcg64_32 = distinct ulong;
fn void Pcg64_32.seed(&pcg, char[8] seed)
{
*pcg = bitcast(seed, Pcg64_32);
}
fn uint Pcg64_32.next(&pcg)
{
const ROT_SHIFT = 32 - 5;
ulong* s = (ulong*)pcg;
ulong xor = *s ^ *s >> ((64 - ROT_SHIFT) / 2);
char rot = (char)(*s >> (64 - 5));
*s = *s * MUL_LCG64 + ODD_PHI64;
return ((uint)(xor >> ROT_SHIFT)).rotr(rot);
}
// -------------------------------- Pcg32_16 --------------------------------
def Pcg32_16 = distinct uint;
fn void Pcg32_16.seed(&pcg, char[4] seed)
{
*pcg = bitcast(seed, Pcg32_16);
}
fn ushort Pcg32_16.next(&pcg)
{
const ROT_SHIFT = 16 - 4;
uint* s = (uint*)pcg;
uint xor = *s ^ *s >> ((32 - ROT_SHIFT) / 2);
char rot = (char)(*s >> (32 - 4));
*s = *s * MUL_LCG32 + ODD_PHI32;
return ((ushort)(xor >> ROT_SHIFT)).rotr(rot);
}
// -------------------------------- Pcg16_8 --------------------------------
def Pcg16_8 = distinct ushort;
fn void Pcg16_8.seed(&pcg, char[2] seed)
{
*pcg = bitcast(seed, Pcg16_8);
}
fn char Pcg16_8.next(&pcg)
{
const ROT_SHIFT = 8 - 3;
ushort* s = (ushort*)pcg;
ushort xor = *s ^ *s >> ((16 - ROT_SHIFT) / 2);
char rot = (char)(*s >> (16 - 3));
*s = *s * MUL_LCG16 + ODD_PHI16;
return ((char)(xor >> ROT_SHIFT)).rotr(rot);
}