Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
rand.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
type rng = { mutable state : int64 } type bounded_rng = { mutable state : int64; bound : int64; threshold : int64; } let modulus = 0x7FFF_FFFFL let check_bound bound = assert (Int64.unsigned_compare bound modulus < 0) let init_state seed = let seed = Int64.of_int seed in if seed = 0L then 1L else Int64.(logand seed modulus) let calc_threshold bound = Int64.(unsigned_rem modulus bound) let create_rng seed : rng = { state = init_state seed } let create_bounded_rng ~bound seed : bounded_rng = let bound = Int64.of_int bound in check_bound bound; let threshold = calc_threshold bound in { state = init_state seed; bound; threshold } let hash' (x : int64) : int64 = let x = Int64.(mul x 48271L) in Int64.(unsigned_rem x modulus) let hash_int (x : int) : int = Int64.to_int @@ hash' (Int64.of_int x) let gen' (rng : rng) (bound : int64) : int64 = let rec aux (rng : rng) bound threshold = let x = hash' rng.state in rng.state <- x; if Int64.unsigned_compare x threshold >= 0 then Int64.unsigned_rem x bound else aux rng bound threshold in check_bound bound; aux rng bound (calc_threshold bound) let gen_bounded' (rng : bounded_rng) : int64 = let rec aux (rng : bounded_rng) = let x = hash' rng.state in rng.state <- x; if Int64.unsigned_compare x rng.threshold >= 0 then Int64.unsigned_rem x rng.bound else aux rng in aux rng let global = Random.self_init (); let seed = Random.int 0x0FFF_FFFF in create_rng seed let gen_int (rng : rng) (bound : int) : int = let r = Int64.to_int @@ gen' rng (Int64.of_int bound) in r let gen_int_global bound = gen_int global bound let gen_int_bounded (rng : bounded_rng) : int = let r = Int64.to_int @@ gen_bounded' rng in r