diff options
-rw-r--r-- | rand.c | 41 | ||||
-rw-r--r-- | tests/013/rand.tl | 84 | ||||
-rw-r--r-- | txr.1 | 10 |
3 files changed, 129 insertions, 6 deletions
@@ -40,6 +40,7 @@ #include "arith.h" #include "eval.h" #include "time.h" +#include "buf.h" #include "txr.h" #include "rand.h" @@ -191,8 +192,46 @@ val make_random_state(val seed, val warmup) r->cur = c_num(seed->v.vec[i], self); return rs; + } else if (bufp(seed)) { + ucnum len = c_unum(seed->b.len, self); + mem_t *data = seed->b.data; + + for (i = 0; i < 16; i++) { + if (len >= 4) { + r->state[i] = (((rand32_t) data[0]) << 24 | + ((rand32_t) data[1]) << 16 | + ((rand32_t) data[2]) << 8 | + ((rand32_t) data[3])); + data += 4; + len -= 4; + } else if (len == 0) { + r->state[i] = 0; + } else { + switch (len % 4) { + case 0: + r->state[i] = 0; + len = 0; + break; + case 1: + r->state[i] = (((rand32_t) data[0]) << 24); + len = 0; + break; + case 2: + r->state[i] = (((rand32_t) data[0]) << 24 | + ((rand32_t) data[1]) << 16); + len = 0; + break; + case 3: + r->state[i] = (((rand32_t) data[0]) << 24 | + ((rand32_t) data[1]) << 16 | + ((rand32_t) data[2]) << 8); + len = 0; + break; + } + } + } } else { - uw_throwf(error_s, lit("~a: seed ~s is not a number"), + uw_throwf(error_s, lit("~a: unable to seed random state with ~s"), self, seed, nao); } diff --git a/tests/013/rand.tl b/tests/013/rand.tl new file mode 100644 index 00000000..f593c39c --- /dev/null +++ b/tests/013/rand.tl @@ -0,0 +1,84 @@ +(load "../common") + +(mtest + (random-state-get-vec (make-random-state #b'' 0)) + #(740765398 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #b'FF' 0)) + #(4278190080 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #b'FFFF' 0)) + #(4294901760 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #b'FFFFFF' 0)) + #(4294967040 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #b'FFFFFFFF' 0)) + #(4294967295 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #b'FFFFFFFFFF' 0)) + #(4294967295 4278190080 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state (make-buf (* 4 16) #xff) 0)) + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 0) + (random-state-get-vec (make-random-state (make-buf (* 5 16) #xff) 0)) + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 0)) + +(mtest + (random-state-get-vec (make-random-state 0 0)) + #(740765398 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #xFF 0)) + #(255 1304255849 3309840409 338361566 4155223728 1162561521 4236628653 + 446542199 639181595 1801947880 2890206840 2695457564 2292665861 + 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #xFFFF 0)) + #(65535 1304255849 3309840409 338361566 4155223728 1162561521 4236628653 + 446542199 639181595 1801947880 2890206840 2695457564 2292665861 + 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #xFFFFFF 0)) + #(16777215 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #xFFFFFFFF 0)) + #(4294967295 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state #xFFFFFFFFFF 0)) + #(4294967295 255 3309840409 338361566 4155223728 1162561521 4236628653 + 446542199 639181595 1801947880 2890206840 2695457564 2292665861 + 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state (expt 2 (* 8 4 16)) 0)) + #(740765398 1304255849 3309840409 338361566 4155223728 1162561521 + 4236628653 446542199 639181595 1801947880 2890206840 2695457564 + 2292665861 3251351234 2171649709 704313206 0) + (random-state-get-vec (make-random-state (pred (expt 2 (* 8 4 16))) 0)) + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 0) + (random-state-get-vec (make-random-state (pred (expt 2 (* 8 4 17))) 0)) + #(4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 4294967295 4294967295 + 4294967295 4294967295 4294967295 4294967295 0)) + +(mtest + (random-state-get-vec (make-random-state + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))) + #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + (random-state-get-vec (make-random-state + #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17))) + #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17) + (random-state-get-vec (make-random-state + #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17) 10)) + #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)) @@ -61669,9 +61669,9 @@ an object of the same kind as what is stored in the .code *random-state* variable. -The seed, if specified, must be either an integer value, an -existing random state object, or a vector returned from a call -to the function +The seed, if specified, must be an integer value, a buffer, +an existing random state object, or else a vector returned from a call to the +function .codn random-state-get-vec . Note that the sign of the seed is ignored, so that negative seed @@ -61691,8 +61691,8 @@ time increment is a millisecond. Calls to .code make-random-state less than a millisecond apart may predictably produce the same seed. -If an integer seed is specified, then the integer value is mapped to a -pseudorandom sequence, in a platform-independent way. +If an integer or buffer seed is specified, then the integer value is mapped to +a pseudorandom sequence, in a platform-independent way. If an existing random state is specified as a seed, then it is duplicated. The returned random state object is a distinct object which is in the same |