mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/random: fix distribution of random_uint32_range()
This commit is contained in:
parent
42c4460daf
commit
ec5fb4fbda
@ -92,10 +92,7 @@ void random_bytes(uint8_t *buf, size_t size);
|
||||
*
|
||||
* @return a random number on [a,b)-interval
|
||||
*/
|
||||
static inline uint32_t random_uint32_range(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (random_uint32() % (b - a)) + a;
|
||||
}
|
||||
uint32_t random_uint32_range(uint32_t a, uint32_t b);
|
||||
|
||||
#if PRNG_FLOAT
|
||||
/* These real versions are due to Isaku Wada, 2002/01/09 added */
|
||||
|
@ -54,3 +54,30 @@ void random_bytes(uint8_t *target, size_t n)
|
||||
*target++ = *random_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t random_uint32_range(uint32_t a, uint32_t b)
|
||||
{
|
||||
assert(a < b);
|
||||
|
||||
uint32_t divisor, rand_val, range = b - a;
|
||||
uint8_t range_msb = bitarithm_msb(range);
|
||||
|
||||
/* check if range is a power of two */
|
||||
if (!(range & (range - 1))) {
|
||||
divisor = (1 << range_msb) - 1;
|
||||
}
|
||||
else if (range_msb < 31) {
|
||||
/* leftshift for next power of two interval */
|
||||
divisor = (1 << (range_msb + 1)) -1;
|
||||
}
|
||||
else {
|
||||
/* disable modulo operation in loop below */
|
||||
divisor = UINT32_MAX;
|
||||
}
|
||||
/* get random numbers until value is smaller than range */
|
||||
do {
|
||||
rand_val = (random_uint32() & divisor);
|
||||
} while (rand_val >= range);
|
||||
/* return random in range [a,b] */
|
||||
return (rand_val + a);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user