X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Frandom.c;h=a771c97ae624a2dd83bda57c95c062e316b77108;hb=231e128f91f6cc7f23f5d2392dffaa7857f1dcfa;hp=01adda5b0137ecbe06de7439db3848369b179348;hpb=8653d547995d7e702e57106b6c6118a5e16f4326;p=libucw.git diff --git a/lib/random.c b/lib/random.c index 01adda5b..a771c97a 100644 --- a/lib/random.c +++ b/lib/random.c @@ -1,22 +1,58 @@ /* - * Sherlock Library -- Unbiased Range Correction for random() + * UCW Library -- Unbiased Random Numbers * - * (c) 1998 Martin Mares, + * (c) 1998--2006 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. */ -#include +#include "lib/lib.h" + #include -#include "lib.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); + +uns +random_u32(void) +{ + return (random() & 0xffff) | ((random() & 0xffff) << 16); +} uns random_max(uns max) { uns 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; +}