1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
(* Written by Stephen Weeks (sweeks@sweeks.com). *)
(*
* Random number generator based on page 302 of Numerical Recipes in C.
*)
fun once () =
let
fun natFold (start, stop, ac, f) =
let
fun loop (i, ac) =
if i = stop
then ac
else loop (i + 1, f (i, ac))
in loop (start, ac)
end
val niter: int = 4
open Word32
fun make (l: word list) =
let val a = Array.fromList l
in fn i => Array.sub (a, i)
end
val c1 = make [0wxbaa96887, 0wx1e17d32c, 0wx03bdcd3c, 0wx0f33d1b2]
val c2 = make [0wx4b0f3b58, 0wxe874f0c3, 0wx6955c5a6, 0wx55a7ca46]
val half: Word.word = 0w16
fun reverse w = orb (>> (w, half), << (w, half))
fun psdes (lword: word, irword: word): word * word =
natFold
(0, niter, (lword, irword), fn (i, (lword, irword)) =>
let
val ia = xorb (irword, c1 i)
val itmpl = andb (ia, 0wxffff)
val itmph = >> (ia, half)
val ib = itmpl * itmpl + notb (itmph * itmph)
in (irword,
xorb (lword, itmpl * itmph + xorb (c2 i, reverse ib)))
end)
val zero: word = 0wx13
val lword: word ref = ref 0w13
val irword: word ref = ref 0w14
val needTo = ref true
fun word () =
if !needTo
then
let
val (l, i) = psdes (!lword, !irword)
val _ = lword := l
val _ = irword := i
val _ = needTo := false
in
l
end
else (needTo := true
; !irword)
fun loop (i, w) =
if i = 0
then
if w = 0wx132B1B67
then ()
else raise Fail "bug"
else loop (Int.- (i, 1), w + word())
in
loop (150000000, 0w0)
end
structure Main =
struct
fun doit n =
if n = 0
then ()
else (once ()
; doit (n - 1))
end
val _ = Main.doit 2
|