X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Frandom.c;h=a771c97ae624a2dd83bda57c95c062e316b77108;hb=231e128f91f6cc7f23f5d2392dffaa7857f1dcfa;hp=57516fd2f89bae94afa1d079e558c4f65987c685;hpb=5b53087fa5a07ff89d34cf3bf3bc1b28809f05c2;p=libucw.git diff --git a/lib/random.c b/lib/random.c index 57516fd2..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/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; +}