summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rand.c41
-rw-r--r--tests/013/rand.tl84
-rw-r--r--txr.110
3 files changed, 129 insertions, 6 deletions
diff --git a/rand.c b/rand.c
index 6c73f9cf..99fb4c3b 100644
--- a/rand.c
+++ b/rand.c
@@ -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))
diff --git a/txr.1 b/txr.1
index 4daf8073..dfc1d443 100644
--- a/txr.1
+++ b/txr.1
@@ -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