diff options
-rw-r--r-- | rand.c | 27 | ||||
-rw-r--r-- | txr.1 | 15 |
2 files changed, 42 insertions, 0 deletions
@@ -215,6 +215,32 @@ val random_fixnum(val state) return num(rand32(r) & NUM_MAX); } +static val random_float(val state) +{ + struct rand_state *r = coerce(struct rand_state *, + cobj_handle(default_arg(state, random_state), + random_state_s)); + union hack { + volatile double d; + struct { +#if HAVE_LITTLE_ENDIAN + volatile rand32_t lo, hi; +#else + volatile rand32_t hi, lo; +#endif + } r; + } h; + + h.r.lo = rand32(r); + h.r.hi = (rand32(r) & 0xFFFFF) | (1023UL << 20); + + /* The least significant bit of the mantissa is always zero after + * this subtraction, reducing us to 51 bits of precision. + * Still; an attractive approach. + */ + return flo(h.d - 1.0); +} + val random(val state, val modulus) { val self = lit("random"); @@ -334,6 +360,7 @@ void rand_init(void) func_n1o(random_state_get_vec, 0)); reg_fun(intern(lit("random-state-p"), user_package), func_n1(random_state_p)); reg_fun(intern(lit("random-fixnum"), user_package), func_n1o(random_fixnum, 0)); + reg_fun(intern(lit("random-float"), user_package), func_n1o(random_float, 0)); reg_fun(intern(lit("random"), user_package), func_n2(random)); reg_fun(intern(lit("rand"), user_package), func_n2o(rnd, 1)); } @@ -47206,6 +47206,21 @@ argument must be a positive integer. If is 1, then the function returns zero without altering the state of the pseudo-random number generator. +.coNP Function @ random-float +.synb +.mets (random-float <> [ random-state ]) +.syne +.desc +The +.code random-float +function produces a pseudo-random floating-point value in the range [0.0, 1.0). + +The numbers are obtained from a WELL 512 PRNG, whose state is stored in the +random state object given by the argument to the optional +.meta random-state +parameter, which defaults to the value of +.codn *random-state* . + .SS* Time .coNP Functions @ time and @ time-usec .synb |