SCM Repository
Annotation of /sml/branches/SMLNJ/src/smlnj-lib/Util/1347-fix
Parent Directory
|
Revision Log
Revision 26 -
(view)
(download)
Original Path: sml/trunk/src/smlnj-lib/Util/1347-fix
1 : | monnier | 26 | Here is the fix for bug 1047, consisting of a new signature and new |
2 : | structure. | ||
3 : | |||
4 : | Emden | ||
5 : | =============== rand-sig.sml ========================= | ||
6 : | (* rand-sig.sml | ||
7 : | * | ||
8 : | * COPYRIGHT (c) 1993 by AT&T Bell Laboratories. See COPYRIGHT file for details. | ||
9 : | * COPYRIGHT (c) 1998 by AT&T Laboratories. | ||
10 : | * | ||
11 : | * Signature for a simple random number generator. | ||
12 : | * | ||
13 : | *) | ||
14 : | |||
15 : | signature RAND = | ||
16 : | sig | ||
17 : | |||
18 : | type rand = Word31.word | ||
19 : | |||
20 : | val randMin : rand | ||
21 : | val randMax : rand | ||
22 : | |||
23 : | val random : rand -> rand | ||
24 : | (* Given seed, return value randMin <= v <= randMax | ||
25 : | * Iteratively using the value returned by random as the | ||
26 : | * next seed to random will produce a sequence of pseudo-random | ||
27 : | * numbers. | ||
28 : | *) | ||
29 : | |||
30 : | val mkRandom : rand -> unit -> rand | ||
31 : | (* Given seed, return function generating a sequence of | ||
32 : | * random numbers randMin <= v <= randMax | ||
33 : | *) | ||
34 : | |||
35 : | val norm : rand -> real | ||
36 : | (* Map values in the range [randMin,randMax] to (0.0,1.0) *) | ||
37 : | |||
38 : | val range : (int * int) -> rand -> int | ||
39 : | (* Map v, randMin <= v <= randMax, to integer range [i,j] | ||
40 : | * Exception - | ||
41 : | * Fail if j < i | ||
42 : | *) | ||
43 : | |||
44 : | end (* RAND *) | ||
45 : | |||
46 : | ============== rand.sml ===================== | ||
47 : | (* rand.sml | ||
48 : | * | ||
49 : | * COPYRIGHT (c) 1991 by AT&T Bell Laboratories. See COPYRIGHT file for details | ||
50 : | * COPYRIGHT (c) 1998 by AT&T Laboratories. See COPYRIGHT file for details | ||
51 : | * | ||
52 : | * Random number generator taken from Paulson, pp. 170-171. | ||
53 : | * Recommended by Stephen K. Park and Keith W. Miller, | ||
54 : | * Random number generators: good ones are hard to find, | ||
55 : | * CACM 31 (1988), 1192-1201 | ||
56 : | * Updated to include the new preferred multiplier of 48271 | ||
57 : | * CACM 36 (1993), 105-110 | ||
58 : | * Updated to use on Word31. | ||
59 : | * | ||
60 : | * Note: The Random structure provides a better generator. | ||
61 : | *) | ||
62 : | |||
63 : | structure Rand : RAND = | ||
64 : | struct | ||
65 : | |||
66 : | type rand = Word31.word | ||
67 : | type rand' = Int32.int (* internal representation *) | ||
68 : | |||
69 : | val a : rand' = 48271 | ||
70 : | val m : rand' = 2147483647 (* 2^31 - 1 *) | ||
71 : | val m_1 = m - 1 | ||
72 : | val q = m div a | ||
73 : | val r = m mod a | ||
74 : | |||
75 : | val extToInt = Int32.fromLarge o Word31.toLargeInt | ||
76 : | val intToExt = Word31.fromLargeInt o Int32.toLarge | ||
77 : | |||
78 : | val randMin : rand = 0w1 | ||
79 : | val randMax : rand = intToExt m_1 | ||
80 : | |||
81 : | fun chk 0w0 = 1 | ||
82 : | | chk 0wx7fffffff = m_1 | ||
83 : | | chk seed = extToInt seed | ||
84 : | |||
85 : | fun random' seed = let | ||
86 : | val hi = seed div q | ||
87 : | val lo = seed mod q | ||
88 : | val test = a * lo - r * hi | ||
89 : | in | ||
90 : | if test > 0 then test else test + m | ||
91 : | end | ||
92 : | |||
93 : | val random = intToExt o random' o chk | ||
94 : | |||
95 : | fun mkRandom seed = let | ||
96 : | val seed = ref (chk seed) | ||
97 : | in | ||
98 : | fn () => (seed := random' (!seed); intToExt (!seed)) | ||
99 : | end | ||
100 : | |||
101 : | val real_m = Real.fromLargeInt (Int32.toLarge m) | ||
102 : | fun norm s = (Real.fromLargeInt (Word31.toLargeInt s)) / real_m | ||
103 : | |||
104 : | fun range (i,j) = | ||
105 : | if j < i | ||
106 : | then LibBase.failure{module="Random",func="range",msg="hi < lo"} | ||
107 : | else if j = i then fn _ => i | ||
108 : | else let | ||
109 : | val R = Int32.fromInt j - Int32.fromInt i | ||
110 : | val cvt = Word31.toIntX o Word31.fromLargeInt o Int32.toLarge | ||
111 : | in | ||
112 : | if R = m then Word31.toIntX | ||
113 : | else fn s => i + cvt ((extToInt s) mod (R+1)) | ||
114 : | end | ||
115 : | |||
116 : | end (* Rand *) | ||
117 : | |||
118 : | |||
119 : |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |