You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.2 KiB
75 lines
1.2 KiB
3 months ago
|
/*
|
||
|
* UCW Library -- Unbiased Random Numbers
|
||
|
*
|
||
|
* (c) 1998--2006 Martin Mares <mj@ucw.cz>
|
||
|
* (c) 2020 Pavel Charvat <pchar@ucw.cz>
|
||
|
*
|
||
|
* This software may be freely distributed and used according to the terms
|
||
|
* of the GNU Lesser General Public License.
|
||
|
*/
|
||
|
|
||
|
#include <ucw/lib.h>
|
||
|
#include <ucw/random.h>
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
/* We expect the random generator in libc to give at least 30 bits of randomness */
|
||
|
COMPILE_ASSERT(RAND_MAX_RANGE_TEST, RAND_MAX >= (1 << 30)-1);
|
||
|
|
||
|
void
|
||
|
random_set_seed(uint seed)
|
||
|
{
|
||
|
srandom(seed);
|
||
|
}
|
||
|
|
||
|
uint
|
||
|
random_gen_seed(void)
|
||
|
{
|
||
|
uint seed = fastrand_gen_seed_value();
|
||
|
random_set_seed(seed);
|
||
|
return seed;
|
||
|
}
|
||
|
|
||
|
uint
|
||
|
random_u32(void)
|
||
|
{
|
||
|
return (random() & 0xffff) | ((random() & 0xffff) << 16);
|
||
|
}
|
||
|
|
||
|
uint
|
||
|
random_max(uint max)
|
||
|
{
|
||
|
uint r, l;
|
||
|
|
||
|
ASSERT(max <= (1 << 30));
|
||
|
l = (RAND_MAX + 1U) - ((RAND_MAX + 1U) % max);
|
||
|
do
|
||
|
r = random();
|
||
|
while (r >= l);
|
||
|
return r % max;
|
||
|
}
|
||
|
|
||
|
u64
|
||
|
random_u64(void)
|
||
|
{
|
||
|
return
|
||
|
((u64)(random() & 0xffff) << 48) |
|
||
|
((u64)(random() & 0xffffff) << 24) |
|
||
|
(random() & 0xffffff);
|
||
|
}
|
||
|
|
||
|
u64
|
||
|
random_max_u64(u64 max)
|
||
|
{
|
||
|
if (max < (1 << 30))
|
||
|
return random_max(max);
|
||
|
|
||
|
u64 r, l, m;
|
||
|
m = 0xffffffffffffffff;
|
||
|
l = m - (m % max);
|
||
|
do
|
||
|
r = random_u64();
|
||
|
while (r >= l);
|
||
|
return r % max;
|
||
|
}
|