mirror of
https://github.com/owntone/owntone-server.git
synced 2025-03-31 01:33:44 -04:00
Replace rng_rand_range() with GLib's g_rand_int_range() that works better
This commit is contained in:
parent
5e9c245e39
commit
ffcf100c00
34
src/rng.c
34
src/rng.c
@ -88,22 +88,40 @@ rng_rand(struct rng_ctx *ctx)
|
|||||||
return ctx->iy;
|
return ctx->iy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Integer in [min, max[, min >= 0 */
|
/* Integer in [min, max[ */
|
||||||
|
/* Taken from GLib 2.0 v2.25.3, g_rand_int_range(), GPLv2+ */
|
||||||
int32_t
|
int32_t
|
||||||
rng_rand_range(struct rng_ctx *ctx, int32_t min, int32_t max)
|
rng_rand_range(struct rng_ctx *ctx, int32_t min, int32_t max)
|
||||||
{
|
{
|
||||||
int32_t res;
|
int32_t res;
|
||||||
int32_t range;
|
int32_t dist;
|
||||||
|
uint32_t maxvalue;
|
||||||
|
uint32_t leftover;
|
||||||
|
|
||||||
range = max - min;
|
dist = max - min;
|
||||||
|
|
||||||
res = rng_rand(ctx);
|
if (dist <= 0)
|
||||||
res = (int32_t)((double)range * ((1.0 / 2147483647.0) * (double)res));
|
return min;
|
||||||
|
|
||||||
if (min > 0)
|
/* maxvalue is set to the predecessor of the greatest
|
||||||
res += min;
|
* multiple of dist less or equal 2^32. */
|
||||||
|
if (dist <= 0x80000000u) /* 2^31 */
|
||||||
|
{
|
||||||
|
/* maxvalue = 2^32 - 1 - (2^32 % dist) */
|
||||||
|
leftover = (0x80000000u % dist) * 2;
|
||||||
|
if (leftover >= dist)
|
||||||
|
leftover -= dist;
|
||||||
|
maxvalue = 0xffffffffu - leftover;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maxvalue = dist - 1;
|
||||||
|
do
|
||||||
|
res = rng_rand(ctx);
|
||||||
|
while (res > maxvalue);
|
||||||
|
|
||||||
return res;
|
res %= dist;
|
||||||
|
|
||||||
|
return min + res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fisher-Yates shuffling algorithm
|
/* Fisher-Yates shuffling algorithm
|
||||||
|
Loading…
x
Reference in New Issue
Block a user