|
| 1 | +#include "random.h" |
| 2 | +#include "std/memfunctions.h" |
| 3 | + |
| 4 | +rng_t global_rng; |
| 5 | + |
| 6 | +void rng_seed(rng_t* rng, uint64_t seed){ //i guess it is "private", no definition in header |
| 7 | + uint64_t z = seed + 0x9E3779B97F4A7C15; |
| 8 | + z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9; |
| 9 | + z = (z ^ (z >> 27)) *0x94D049BB133111EB; |
| 10 | + rng->s0 = z ^ (z >> 31); |
| 11 | + |
| 12 | + z = seed + 0x9E3779B97F4A7C15 + 1; |
| 13 | + z = (z ^ (z >> 30)) *0xBF58476D1CE4E5B9; |
| 14 | + z = (z ^ (z >> 27))*0x94D049BB133111EB; |
| 15 | + rng->s1 = z ^ (z >> 31); |
| 16 | +} |
| 17 | + |
| 18 | +uint64_t rng_next64(rng_t* rng){ |
| 19 | + uint64_t s0 = rng->s0; |
| 20 | + uint64_t s1 = rng->s1; |
| 21 | + uint64_t result = s0 + s1; |
| 22 | + |
| 23 | + s1 ^= s0; |
| 24 | + rng->s0 = rotl(s0, 55)^s1^(s1 << 14); |
| 25 | + rng->s1 = rotl(s1, 36); |
| 26 | + |
| 27 | + return result; |
| 28 | +} |
| 29 | + |
| 30 | +uint32_t rng_next32(rng_t* rng){ |
| 31 | + return (uint32_t)(rng_next64(rng) >> 32); |
| 32 | +} |
| 33 | + |
| 34 | +uint16_t rng_next16(rng_t* rng){ |
| 35 | + return (uint16_t)(rng_next64(rng) >> 48); |
| 36 | +} |
| 37 | + |
| 38 | +uint8_t rng_next8(rng_t* rng){ |
| 39 | + return (uint8_t)(rng_next64(rng) >> 56); |
| 40 | +} |
| 41 | + |
| 42 | +uint64_t rng_between64(rng_t* rng, uint64_t min, uint64_t max){ |
| 43 | + if (max <= min) return min; |
| 44 | + return rng_next64(rng) % (max - min) + min; |
| 45 | +} |
| 46 | + |
| 47 | +uint32_t rng_between32(rng_t* rng, uint32_t min, uint32_t max){ |
| 48 | + if (max <= min) return min; |
| 49 | + return rng_next64(rng) % (max - min) + min; |
| 50 | +} |
| 51 | + |
| 52 | +uint16_t rng_between16(rng_t* rng, uint16_t min, uint16_t max){ |
| 53 | + if (max <= min) return min; |
| 54 | + return (uint16_t)(rng_next64(rng) % (max - min)) + min; |
| 55 | +} |
| 56 | + |
| 57 | +uint8_t rng_between8(rng_t* rng, uint8_t min, uint8_t max){ |
| 58 | + if (max <= min) return min; |
| 59 | + return (uint8_t)(rng_next64(rng) % (max - min)) + min; |
| 60 | +} |
| 61 | + |
| 62 | +void rng_fill64(rng_t* rng, uint64_t* dst, uint32_t count){ |
| 63 | + for (uint32_t i = 0; i < count; i++) |
| 64 | + dst[i] = rng_next64(rng); |
| 65 | +} |
| 66 | + |
| 67 | +void rng_fill32(rng_t* rng, uint32_t* dst, uint32_t count){ |
| 68 | + for (uint32_t i = 0; i < count; i++) |
| 69 | + dst[i] = rng_next32(rng); |
| 70 | +} |
| 71 | + |
| 72 | +void rng_fill16(rng_t* rng, uint16_t* dst, uint32_t count){ |
| 73 | + for (uint32_t i = 0; i < count; i++) |
| 74 | + dst[i] = rng_next16(rng); |
| 75 | +} |
| 76 | + |
| 77 | +void rng_fill8(rng_t* rng, uint8_t* dst, uint32_t count){ |
| 78 | + for (uint32_t i = 0; i < count; i++) |
| 79 | + dst[i] = rng_next8(rng); |
| 80 | +} |
| 81 | + |
| 82 | +void rng_init_global(uint64_t seed) { |
| 83 | + rng_seed(&global_rng, seed); |
| 84 | +} |
0 commit comments