Fix biased output of randi_range
This commit is contained in:
parent
13e93fe904
commit
31faa1f226
|
@ -58,12 +58,18 @@ public:
|
||||||
_FORCE_INLINE_ real_t randfn(real_t mean = 0.0, real_t deviation = 1.0) { return randbase.randfn(mean, deviation); }
|
_FORCE_INLINE_ real_t randfn(real_t mean = 0.0, real_t deviation = 1.0) { return randbase.randfn(mean, deviation); }
|
||||||
|
|
||||||
_FORCE_INLINE_ int randi_range(int from, int to) {
|
_FORCE_INLINE_ int randi_range(int from, int to) {
|
||||||
unsigned int ret = randbase.rand();
|
int range;
|
||||||
if (to < from) {
|
int min;
|
||||||
return ret % (from - to + 1) + to;
|
if (to > from) {
|
||||||
} else {
|
range = to - from + 1;
|
||||||
return ret % (to - from + 1) + from;
|
min = from;
|
||||||
|
} else if (to < from) {
|
||||||
|
range = from - to + 1;
|
||||||
|
min = to;
|
||||||
|
} else { // from == to
|
||||||
|
return from;
|
||||||
}
|
}
|
||||||
|
return randbase.rand(range) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomNumberGenerator() {}
|
RandomNumberGenerator() {}
|
||||||
|
|
|
@ -81,6 +81,10 @@ public:
|
||||||
current_seed = pcg.state;
|
current_seed = pcg.state;
|
||||||
return pcg32_random_r(&pcg);
|
return pcg32_random_r(&pcg);
|
||||||
}
|
}
|
||||||
|
_FORCE_INLINE_ uint32_t rand(uint32_t bounds) {
|
||||||
|
current_seed = pcg.state;
|
||||||
|
return pcg32_boundedrand_r(&pcg, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
// Obtaining floating point numbers in [0, 1] range with "good enough" uniformity.
|
// Obtaining floating point numbers in [0, 1] range with "good enough" uniformity.
|
||||||
// These functions sample the output of rand() as the fraction part of an infinite binary number,
|
// These functions sample the output of rand() as the fraction part of an infinite binary number,
|
||||||
|
|
|
@ -23,3 +23,13 @@ void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq)
|
||||||
rng->state += initstate;
|
rng->state += initstate;
|
||||||
pcg32_random_r(rng);
|
pcg32_random_r(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Source from https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.c
|
||||||
|
uint32_t pcg32_boundedrand_r(pcg32_random_t *rng, uint32_t bound) {
|
||||||
|
uint32_t threshold = -bound % bound;
|
||||||
|
for (;;) {
|
||||||
|
uint32_t r = pcg32_random_r(rng);
|
||||||
|
if (r >= threshold)
|
||||||
|
return r % bound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,5 +11,6 @@
|
||||||
typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t;
|
typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t;
|
||||||
uint32_t pcg32_random_r(pcg32_random_t* rng);
|
uint32_t pcg32_random_r(pcg32_random_t* rng);
|
||||||
void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq);
|
void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq);
|
||||||
|
uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t bound);
|
||||||
|
|
||||||
#endif // RANDOM_H
|
#endif // RANDOM_H
|
||||||
|
|
Loading…
Reference in New Issue