(* Note: Because of a lack of unsigned integers *) (* in OCaml, this code will give numbers in the *) (* range [-2^31, 2^31-1] for integers. *) open Int32 (* These are borrowed from F# for bitwise operations. *) let ( &&& ) a b = logand a b let ( ||| ) a b = logor a b let ( ^^^ ) a b = logxor a b let ( >>> ) a b = shift_right_logical a b let ( <<< ) a b = shift_left a b type state = { mt : int32 array; mutable mti : int; } let n = 624 and m = 397 and upper_mask = 0x80000000l and lower_mask = 0x7fffffffl and mag01 = [| 0x0l; 0x9908b0dfl |] and mask_b = 0x9d2c5680l and mask_c = 0xefc60000l let init_state () = { mt = Array.make n 0l; mti = n; } let make seed = let state = init_state () in state.mt.(0) <- (seed &&& 0xffffffffl); for i = 1 to n - 1 do state.mt.(i) <- (add (mul 1812433253l (state.mt.(i - 1) ^^^ (state.mt.(i - 1) >>> 30))) (of_int i)) done; state let gen_words state = let y = ref 0l in for i = 0 to n - m - 1 do y := ((state.mt.(i) &&& upper_mask) ||| (state.mt.(i + 1) &&& lower_mask)); state.mt.(i) <- state.mt.(i + m) ^^^ (!y >>> 1) ^^^ (mag01.(to_int (!y &&& one))) done; for i = n - m to n - 2 do y := (state.mt.(i) &&& upper_mask) ||| (state.mt.(i + 1) &&& lower_mask); state.mt.(i) <- state.mt.(i + m - n) ^^^ (!y >>> 1) ^^^ (mag01.(to_int (!y &&& one))) done; y := (state.mt.(n - 1) &&& upper_mask) ||| (state.mt.(0) &&& lower_mask); state.mt.(n - 1) <- state.mt.(m - 1) ^^^ (!y >>> 1) ^^^ (mag01.(to_int (!y &&& one))); state.mti <- 0 let genint32 state = if (state.mti >= n) then gen_words state; let y = ref state.mt.(state.mti) in y := !y ^^^ (!y >>> 11); y := !y ^^^ ((!y <<< 7) &&& mask_b); y := !y ^^^ ((!y <<< 15) &&& mask_c); y := !y ^^^ (!y >>> 18); state.mti <- state.mti + 1; !y let int32 () = let rand = genint32 (make (of_float (Unix.time ()))) in rand