misc/random: add mp_rand_in_range32()

removes awkward back-and-forth int -> double -> int conversion.
the last step also broke uniformity, though it likely doesn't
matter much in mpv's playlist shuffle context.
This commit is contained in:
NRK authored and sfan5 committed 2025-04-02 17:28:49 +02:00
1 parent b968dec77d
commit 22f4ff44c5
3 files changed
+24 -2

No files matched your search

+16
View File
@@ -22,6 +22,8 @@
#include <libavutil/random_seed.h>
#include "common/common.h"
#include "misc/mp_assert.h"
#include "osdep/timer.h"
#include "random.h"
@@ -84,3 +86,17 @@ double mp_rand_next_double(mp_rand_state *s)
{
return (mp_rand_next(s) >> 11) * 0x1.0p-53;
}
// <https://web.archive.org/web/20250321082025/
// https://www.pcg-random.org/posts/bounded-rands.html#bitmask-with-rejection-unbiased-apples-method>
uint32_t mp_rand_in_range32(mp_rand_state *s, uint32_t min, uint32_t max)
{
mp_assert(min < max);
uint32_t range = max - min;
uint32_t mask = mp_round_next_power_of_2(range) - 1;
uint32_t ret;
do {
ret = mp_rand_next(s) & mask;
} while (ret >= range);
return min + ret;
}
+6
View File
@@ -46,3 +46,9 @@ uint64_t mp_rand_next(mp_rand_state *s);
* distribution, and update the state accordingly.
*/
double mp_rand_next_double(mp_rand_state *s);
/*
* Return a 32 bit integer in the range [min, max) with uniform distribution.
* Caller should ensure `min < max`.
*/
uint32_t mp_rand_in_range32(mp_rand_state *s, uint32_t min, uint32_t max);