Random.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include "core/Random.h"
  2. static const size_t M = 7;
  3. void coreInitRandom(CoreRandom* r, u32 seed) {
  4. for(size_t i = 0; i < CORE_ARRAY_LENGTH(r->data); i++) {
  5. r->data[i] = seed;
  6. seed = seed * 7 + 31;
  7. }
  8. }
  9. static void update(CoreRandom* r) {
  10. static const u32 map[2] = {0, 0x8EBFD028};
  11. static const size_t LENGTH = CORE_ARRAY_LENGTH(r->data);
  12. for(size_t i = 0; i < LENGTH - M; i++) {
  13. r->data[i] = r->data[i + M] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1];
  14. }
  15. for(size_t i = LENGTH - M; i < LENGTH; i++) {
  16. r->data[i] =
  17. r->data[i + (M - LENGTH)] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1];
  18. }
  19. r->index = 0;
  20. }
  21. #define CORE_LIMIT(value, min, max) (min + value % (max - min))
  22. static u32 next(CoreRandom* r) {
  23. if(r->index >= CORE_ARRAY_LENGTH(r->data)) {
  24. update(r);
  25. }
  26. u32 u = r->data[r->index++];
  27. u ^= (u << 7) & 0x2B5B2500;
  28. u ^= (u << 15) & 0xDB8B0000;
  29. u ^= (u >> 16);
  30. return u;
  31. }
  32. u32 coreRandomU32(CoreRandom* r, u32 min, u32 exclusiveMax) {
  33. u32 u = next(r);
  34. return CORE_LIMIT(u, min, exclusiveMax);
  35. }
  36. i32 coreRandomI32(CoreRandom* r, i32 min, i32 exclusiveMax) {
  37. i32 i = (i32)(next(r) >> 1);
  38. return CORE_LIMIT(i, min, exclusiveMax);
  39. }
  40. size_t coreRandomSize(CoreRandom* r, size_t min, size_t exclusiveMax) {
  41. size_t s = next(r);
  42. return CORE_LIMIT(s, min, exclusiveMax);
  43. }
  44. bool coreRandomBool(CoreRandom* r) {
  45. return next(r) & 1;
  46. }
  47. float coreRandomFloat(CoreRandom* r) {
  48. u32 u = next(r);
  49. float f = (float)u / (float)0xFFFFFFF;
  50. return f >= 1.0f ? coreRandomFloat(r) : f;
  51. }