quadrants/source/core/random.cpp

49 lines
1.7 KiB
C++
Raw Normal View History

2023-02-27 14:02:30 +01:00
#include <stdlib.h>
/**
* Raw memory type used for representing the maximum random size of a value.
*/
typedef long unsigned Seed;
/**
* State machine for an instance of XOR shift-based pseudo-random number generation.
*/
typedef struct XorShifter {
/**
* Initial seed state iniailized when creating the pseudo-random number generator, set by
* either manually arranging the memory or by calling [CreateXorShifter(seed_t const)]. Every
* time a new random number is generated, usually by calling
* [GetXorShifterValue(XorShifter* const, long const, long const)], this value will be mutated
* with the new iteration value.
*/
Seed seed;
} XorShifter;
/**
* Creates a [XorShifter] with the given `seed` as initial entropy. Note that like all pseudo-
* random number generators, the initial seed makes all sequential operations deterministic to the
* value. I.e. running the same program twice with the same seed will yield the same results. To
* get more entropic values either pass in the current UNIX timestamp value of the device or poll
* the device's system-dependant entropy device for a new seed each run.
*/
XorShifter CreateXorShifter(Seed const seed) {
return (XorShifter){seed};
}
/**
* Returns the next pseudo-random iteration in the `xorShifter`'s seeded sequence, reduced down a
* range between `min` and `max`, provided the `xorShifter`'s seed is greater than `0`.
*/
long const GetXorShifterValue(XorShifter* const xorShifter, long const min, long const max) {
if (xorShifter->seed) {
Seed value = xorShifter->seed;
value ^= value << 13;
value ^= value >> 17;
value ^= value << 5;
return labs((long)(xorShifter->seed = value)) % (labs(max - min) + 1) + min;
}
return 0;
}