FENIX_libc/stdlib/rand.c

65 lines
1.4 KiB
C

/*
* This rand() implementation is based on the Mersenne Twister.
* Specifically, it's a C implementation of the pseudocode
* implementation that can be found on the Wikipedia article for
* the Mersenne Twister.
*
* Did we have to do a Mersenne Twister? No. No, we did not.
* Did we? Fuck yes, we did.
*
* Love,
* Kat
*/
#include <stdlib.h>
static int _rand_state[624] = { 0 };
static unsigned int _rand_seed = 5489;
static int _rand_index = 625;
void _rand_init(unsigned int seed) {
_rand_index = 624;
_rand_state[0] = seed;
int i = 0;
for(i = 1; i < 624; i++) {
_rand_state[i] = 1812433253 ;
_rand_state[i] *= _rand_state[i-1] ^ (_rand_state[i-1] >> 30);
_rand_state[i] += i;
}
}
void _rand_twist() {
int i = 0, x, xA;
for(i = 0; i < 624; i++) {
x = _rand_state[i] & 0xFFFF0000 + (_rand_state[(i + 1) % 624] & 0xFFFF);
xA = x % 2 == 0 ? x >> 1 : (x >> 1) ^ 0x9908B0DF;
_rand_state[i] = _rand_state[(i + 397) % 624] ^ xA;
}
_rand_index = 0;
}
int rand(void) {
int y;
if(_rand_index > 624) {
_rand_init(_rand_seed);
}
if(_rand_index >= 624) {
_rand_twist();
}
y = _rand_state[_rand_index];
y ^= y >> 11;
y ^= (y << 7) & 0x9D2C5680;
y ^= (y << 15) & 0xEFC60000;
y ^= (y >> 18);
_rand_index++;
return y % RAND_MAX;
}
void srand(unsigned int seed) {
_rand_seed = seed;
_rand_index = 625;
}