File: psdes-random.sml

package info (click to toggle)
mlton 20100608-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 34,980 kB
  • ctags: 69,089
  • sloc: ansic: 18,421; lisp: 2,879; makefile: 1,570; sh: 1,325; pascal: 256; asm: 97
file content (73 lines) | stat: -rw-r--r-- 1,968 bytes parent folder | download | duplicates (7)
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