Fix modulo bias in GetRandomValue(); implement rejection sampling for uniformity
This commit is contained in:
parent
8115b7e922
commit
1a901da9a0
24
src/rcore.c
24
src/rcore.c
|
|
@ -1743,7 +1743,29 @@ int GetRandomValue(int min, int max)
|
||||||
TRACELOG(LOG_WARNING, "Invalid GetRandomValue() arguments, range should not be higher than %i", RAND_MAX);
|
TRACELOG(LOG_WARNING, "Invalid GetRandomValue() arguments, range should not be higher than %i", RAND_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = (rand()%(abs(max - min) + 1) + min);
|
int range = (max - min) + 1;
|
||||||
|
|
||||||
|
// Degenerate/overflow case: fall back to min (same behavior as "always min" instead of UB)
|
||||||
|
if (range <= 0)
|
||||||
|
{
|
||||||
|
value = min;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Rejection sampling to get a uniform integer in [min, max]
|
||||||
|
unsigned long c = (unsigned long)RAND_MAX + 1UL; // number of possible rand() results
|
||||||
|
unsigned long m = (unsigned long)range; // size of the target interval
|
||||||
|
unsigned long t = c - (c % m); // largest multiple of m <= c
|
||||||
|
unsigned long r;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
r = (unsigned long)rand();
|
||||||
|
}
|
||||||
|
while (r >= t);
|
||||||
|
|
||||||
|
value = min + (int)(r % m);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user