Luna/libs/libc/src/rand.cpp

64 lines
1.4 KiB
C++
Raw Normal View History

2022-10-15 14:31:08 +00:00
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
2022-10-15 14:31:08 +00:00
#include <stdlib.h>
typedef uint32_t word_t;
#define STATE_SIZE 624
#define MIDDLE 397
#define INIT_SHIFT 30
#define INIT_FACT 1812433253
#define TWIST_MASK 0x9908b0df
#define SHIFT1 11
#define MASK1 0xffffffff
#define SHIFT2 7
#define MASK2 0x9d2c5680
#define SHIFT3 15
#define MASK3 0xefc60000
#define SHIFT4 18
2022-10-15 14:31:08 +00:00
#define LOWER_MASK 0x7fffffff
#define UPPER_MASK (~(word_t)LOWER_MASK)
static word_t state[STATE_SIZE];
static size_t index = STATE_SIZE + 1;
static void twist()
2022-10-15 14:31:08 +00:00
{
for (size_t i = 0; i < STATE_SIZE; i++)
{
word_t x = (state[i] & UPPER_MASK) | (state[(i + 1) % STATE_SIZE] & LOWER_MASK);
x = (x >> 1) ^ (x & 1 ? TWIST_MASK : 0);
state[i] = state[(i + MIDDLE) % STATE_SIZE] ^ x;
}
index = 0;
2022-10-15 14:31:08 +00:00
}
extern "C"
{
int rand()
2022-10-15 14:31:08 +00:00
{
if (index >= STATE_SIZE)
2022-10-15 14:31:08 +00:00
{
assert(index == STATE_SIZE && "Mersenne generator was never seeded");
twist();
2022-10-15 14:31:08 +00:00
}
word_t y = state[index];
y ^= (y >> SHIFT1) & MASK1;
y ^= (y << SHIFT2) & MASK2;
y ^= (y << SHIFT3) & MASK3;
y ^= y >> SHIFT4;
index++;
return y;
2022-10-15 14:31:08 +00:00
}
void srand(unsigned int seed)
2022-10-15 14:31:08 +00:00
{
index = STATE_SIZE;
state[0] = seed;
for (size_t i = 1; i < STATE_SIZE; i++)
state[i] = (word_t)((INIT_FACT * (state[i - 1] ^ (state[i - 1] >> INIT_SHIFT))) + i);
2022-10-15 14:31:08 +00:00
}
}