diff options
Diffstat (limited to 'src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_util_tinyrandom.c')
-rw-r--r-- | src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_util_tinyrandom.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_util_tinyrandom.c b/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_util_tinyrandom.c new file mode 100644 index 000000000..99e4223c5 --- /dev/null +++ b/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_util_tinyrandom.c @@ -0,0 +1,63 @@ +/* + * A tiny random number generator. + * + * Currently used for Math.random(). + * + * http://www.woodmann.com/forum/archive/index.php/t-3100.html + */ + +#include "duk_internal.h" + +#define DUK__UPDATE_RND(rnd) do { \ + (rnd) += ((rnd) * (rnd)) | 0x05; \ + (rnd) = ((rnd) & 0xffffffffU); /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \ + } while (0) + +#define DUK__RND_BIT(rnd) ((rnd) >> 31) /* only use the highest bit */ + +DUK_INTERNAL duk_uint32_t duk_util_tinyrandom_get_bits(duk_hthread *thr, duk_small_int_t n) { + duk_small_int_t i; + duk_uint32_t res = 0; + duk_uint32_t rnd; + + rnd = thr->heap->rnd_state; + + for (i = 0; i < n; i++) { + DUK__UPDATE_RND(rnd); + res <<= 1; + res += DUK__RND_BIT(rnd); + } + + thr->heap->rnd_state = rnd; + + return res; +} + +DUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) { + duk_double_t t; + duk_small_int_t n; + duk_uint32_t rnd; + + /* + * XXX: could make this a lot faster if we create the double memory + * representation directly. Feasible easily (must be uniform random). + */ + + rnd = thr->heap->rnd_state; + + n = 53; /* enough to cover the whole mantissa */ + t = 0.0; + + do { + DUK__UPDATE_RND(rnd); + t += DUK__RND_BIT(rnd); + t /= 2.0; + } while (--n); + + thr->heap->rnd_state = rnd; + + DUK_ASSERT(t >= (duk_double_t) 0.0); + DUK_ASSERT(t < (duk_double_t) 1.0); + + return t; +} |