package stdlib-random
Versioned Random module from the OCaml standard library
Install
Dune Dependency
Authors
Maintainers
Sources
stdlib-random-1.1.0.tbz
sha256=8b930182fe680b8b96ad1e082b87a17c8011d95a670f557c703035f04f812559
sha512=c406f3598664593676c0cfcc9f248c0c6114602ab0cd9f2c9ab03243debc534515ab61eb8de8c92bdbbed2a6c916441606263e7e577b1a989da41660315c12dc
doc/src/stdlib-random.v5o/random5o.ml.html
Source file random5o.ml
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
(**************************************************************************) (* *) (* OCaml *) (* *) (* Damien Doligez, projet Para, INRIA Rocquencourt *) (* Xavier Leroy, projet Cambium, College de France and Inria *) (* *) (* Copyright 1996 Institut National de Recherche en Informatique et *) (* en Automatique. *) (* *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Lesser General Public License version 2.1, with the *) (* special exception on linking described in the file LICENSE. *) (* *) (**************************************************************************) (* Pseudo-random number generator *) external random_seed: unit -> int array = "caml_sys_random_seed" module State = struct open Bigarray type t = (int64, int64_elt, c_layout) Array1.t let next = Prng.next let create () : t = Array1.create Int64 C_layout 4 let set s i1 i2 i3 i4 = Array1.unsafe_set s 0 (Int64.logor i1 1L); (* must be odd *) Array1.unsafe_set s 1 i2; Array1.unsafe_set s 2 (if i3 <> 0L then i3 else 1L); (* must not be 0 *) Array1.unsafe_set s 3 (if i4 <> 0L then i4 else 2L) (* must not be 0 *) let mk i1 i2 i3 i4 = let s = create () in set s i1 i2 i3 i4; s let serialization_prefix = "lxm1:" (* "lxm" denotes the algorithm currently in use, and '1' is a version number. We should update this prefix if we change the Random algorithm or the serialization format, so that users get a clean error instead of believing that they faithfully reproduce their previous state and in fact get a differrent stream. Note that there is no constraint to keep the same "<name><ver>:<data>" format or message size in future versions, we could change the format completely if we wanted as long as there is no confusion possible with the previous formats. *) let serialization_prefix_len = String.length serialization_prefix (* Compatibility functions Imported from standard library *) #if OCAML_VERSION < (4,8,0) let set_int64_le b off n = let n = ref n in for i = 0 to 7 do Bytes.set b (off+i) Int64.(Char.unsafe_chr @@ Int64.to_int @@ logand !n 0xFFL); n := Int64.(shift_right !n 8) done #else let set_int64_le = Bytes.set_int64_le #endif #if OCAML_VERSION < (4,13,0) let get_int64_le s off = let res = ref Int64.zero in for i = 7 downto 0 do let v = Int64.of_int (Char.code s.[off+i]) in res := Int64.(add v (shift_left !res 8)) done; !res let starts_with ~prefix s = let open String in let len_s = length s and len_pre = length prefix in let rec aux i = if i = len_pre then true else if unsafe_get s i <> unsafe_get prefix i then false else aux (i + 1) in len_s >= len_pre && aux 0 #else let get_int64_le = String.get_int64_le let starts_with = String.starts_with #endif let to_binary_string s = let prefix = serialization_prefix in let preflen = serialization_prefix_len in let buf = Bytes.create (preflen + 4 * 8) in Bytes.blit_string prefix 0 buf 0 preflen; for i = 0 to 3 do Bytes.set_int64_le buf (preflen + i * 8) (Array1.get s i) done; Bytes.unsafe_to_string buf let of_binary_string buf = let prefix = serialization_prefix in let preflen = serialization_prefix_len in if String.length buf <> preflen + 4 * 8 || not (starts_with ~prefix buf) then failwith ("Random.State.of_binary_string: expected a format \ compatible with OCaml " ^ Sys.ocaml_version); let i1 = get_int64_le buf (preflen + 0 * 8) in let i2 = get_int64_le buf (preflen + 1 * 8) in let i3 = get_int64_le buf (preflen + 2 * 8) in let i4 = get_int64_le buf (preflen + 3 * 8) in mk i1 i2 i3 i4 let assign (dst: t) (src: t) = Array1.blit src dst let copy s = let s' = create() in assign s' s; s' (* The seed is an array of integers. It can be just one integer, but it can also be 12 or more bytes. To hide the difference, we serialize the array as a sequence of bytes, then hash the sequence with MD5 (Digest.bytes). MD5 gives only 128 bits while we need 256 bits, so we hash twice with different suffixes. *) let reinit s seed = let n = Array.length seed in let b = Bytes.create (n * 8 + 1) in for i = 0 to n-1 do set_int64_le b (i * 8) (Int64.of_int seed.(i)) done; Bytes.set b (n * 8) '\x01'; let d1 = Digest.bytes b in Bytes.set b (n * 8) '\x02'; let d2 = Digest.bytes b in set s (get_int64_le d1 0) (get_int64_le d1 8) (get_int64_le d2 0) (get_int64_le d2 8) let make seed = let s = create() in reinit s seed; s let make_self_init () = make (random_seed ()) (* Return 30 random bits as an integer 0 <= x < 1073741824 *) let bits s = Int64.to_int (next s) land 0x3FFF_FFFF (* Return an integer between 0 (included) and [bound] (excluded) *) let rec intaux s n = let r = bits s in let v = r mod n in if r - v > 0x3FFFFFFF - n + 1 then intaux s n else v let int s bound = if bound > 0x3FFFFFFF || bound <= 0 then invalid_arg "Random.int" else intaux s bound (* Return an integer between 0 (included) and [bound] (excluded). [bound] may be any positive [int]. *) let rec int63aux s n = let r = Int64.to_int (next s) land max_int in let v = r mod n in if r - v > max_int - n + 1 then int63aux s n else v let full_int s bound = if bound <= 0 then invalid_arg "Random.full_int" else if bound > 0x3FFFFFFF then int63aux s bound else intaux s bound (* Return 32 random bits as an [int32] *) let bits32 s = Int64.to_int32 (next s) (* Return an [int32] between 0 (included) and [bound] (excluded). *) let rec int32aux s n = let r = Int32.shift_right_logical (bits32 s) 1 in let v = Int32.rem r n in if Int32.(sub r v > add (sub max_int n) 1l) then int32aux s n else v let int32 s bound = if bound <= 0l then invalid_arg "Random.int32" else int32aux s bound (* Return 64 random bits as an [int64] *) let bits64 s = next s (* Return an [int64] between 0 (included) and [bound] (excluded). *) let rec int64aux s n = let r = Int64.shift_right_logical (bits64 s) 1 in let v = Int64.rem r n in if Int64.(sub r v > add (sub max_int n) 1L) then int64aux s n else v let int64 s bound = if bound <= 0L then invalid_arg "Random.int64" else int64aux s bound (* Return 32 or 64 random bits as a [nativeint] *) let nativebits = if Nativeint.size = 32 then fun s -> Nativeint.of_int32 (bits32 s) else fun s -> Int64.to_nativeint (bits64 s) (* Return a [nativeint] between 0 (included) and [bound] (excluded). *) let nativeint = if Nativeint.size = 32 then fun s bound -> Nativeint.of_int32 (int32 s (Nativeint.to_int32 bound)) else fun s bound -> Int64.to_nativeint (int64 s (Int64.of_nativeint bound)) (* Return a float 0 < x < 1 uniformly distributed among the multiples of 2^-53 *) let rec rawfloat s = let b = next s in let n = Int64.shift_right_logical b 11 in if n <> 0L then Int64.to_float n *. 0x1.p-53 else rawfloat s (* Return a float between 0 and [bound] *) let float s bound = rawfloat s *. bound (* Return a random Boolean *) let bool s = next s < 0L (* Split a new PRNG off the given PRNG *) let split s = let i1 = bits64 s in let i2 = bits64 s in let i3 = bits64 s in let i4 = bits64 s in mk i1 i2 i3 i4 end let mk_default () = (* This is the state obtained with [State.make [| 314159265 |]]. *) State.mk (-6196874289567705097L) 586573249833713189L (-8591268803865043407L) 6388613595849772044L #if OCAML_VERSION < (5,0,0) let random_key = mk_default () let bits () = State.bits random_key let int bound = State.int random_key bound let full_int bound = State.full_int random_key bound let int32 bound = State.int32 random_key bound let nativeint bound = State.nativeint random_key bound let int64 bound = State.int64 random_key bound let float scale = State.float random_key scale let bool () = State.bool random_key let bits32 () = State.bits32 random_key let bits64 () = State.bits64 random_key let nativebits () = State.nativebits random_key let full_init seed = State.reinit random_key seed let init seed = full_init [| seed |] let self_init () = full_init (random_seed()) (* Splitting *) let split () = State.split random_key (* Manipulating the current state. *) let get_state () = State.copy random_key let set_state s = State.assign random_key s #else let random_key = Domain.DLS.new_key ~split_from_parent:State.split mk_default let bits () = State.bits (Domain.DLS.get random_key) let int bound = State.int (Domain.DLS.get random_key) bound let full_int bound = State.full_int (Domain.DLS.get random_key) bound let int32 bound = State.int32 (Domain.DLS.get random_key) bound let nativeint bound = State.nativeint (Domain.DLS.get random_key) bound let int64 bound = State.int64 (Domain.DLS.get random_key) bound let float scale = State.float (Domain.DLS.get random_key) scale let bool () = State.bool (Domain.DLS.get random_key) let bits32 () = State.bits32 (Domain.DLS.get random_key) let bits64 () = State.bits64 (Domain.DLS.get random_key) let nativebits () = State.nativebits (Domain.DLS.get random_key) let full_init seed = State.reinit (Domain.DLS.get random_key) seed let init seed = full_init [| seed |] let self_init () = full_init (random_seed()) (* Splitting *) let split () = State.split (Domain.DLS.get random_key) (* Manipulating the current state. *) let get_state () = State.copy (Domain.DLS.get random_key) let set_state s = State.assign (Domain.DLS.get random_key) s #endif
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>