Skip to content

Commit

Permalink
Merge pull request #43184 from Chaosus/fix_randi_range_biased
Browse files Browse the repository at this point in the history
Fix biased output of randi_range
  • Loading branch information
akien-mga authored Oct 30, 2020
2 parents b1ed10d + 31faa1f commit f98db72
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
16 changes: 11 additions & 5 deletions core/math/random_number_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ class RandomNumberGenerator : public Reference {
_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) {
unsigned int ret = randbase.rand();
if (to < from) {
return ret % (from - to + 1) + to;
} else {
return ret % (to - from + 1) + from;
int range;
int min;
if (to > from) {
range = to - from + 1;
min = from;
} else if (to < from) {
range = from - to + 1;
min = to;
} else { // from == to
return from;
}
return randbase.rand(range) + min;
}

RandomNumberGenerator() {}
Expand Down
4 changes: 4 additions & 0 deletions core/math/random_pcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class RandomPCG {
current_seed = pcg.state;
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.
// These functions sample the output of rand() as the fraction part of an infinite binary number,
Expand Down
10 changes: 10 additions & 0 deletions thirdparty/misc/pcg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,13 @@ void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq)
rng->state += initstate;
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;
}
}
1 change: 1 addition & 0 deletions thirdparty/misc/pcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t;
uint32_t pcg32_random_r(pcg32_random_t* rng);
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

0 comments on commit f98db72

Please sign in to comment.