Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 6a3462f8 authored by POTTIER Francois's avatar POTTIER Francois
Browse files

Remove incorrect use of [Random.get_state], causing the random number...

Remove incorrect use of [Random.get_state], causing the random number generator to always produce the same number.
parent 6b6aac0c
No related branches found
No related tags found
No related merge requests found
......@@ -11,8 +11,8 @@
(* Uniform random generation of large integers. Copied and adapted from Jane
Street's bignum library. *)
(* [random state range] chooses a [depth] and generates random values using
[R.bits state], called [1 lsl depth] times and concatenated. The
(* [random range] chooses a [depth] and generates random values using
[R.bits()], called [1 lsl depth] times and concatenated. The
preliminary result [n] therefore satisfies [0 <= n < 1 lsl (30 lsl depth)].
In order for the random choice to be uniform between [0] and [range-1],
......@@ -40,39 +40,36 @@ let rec choose_bit_depth_for_range_from range depth =
let choose_bit_depth_for_range (range : Z.t) : int =
choose_bit_depth_for_range_from range 0
let rec random_bigint_at_depth (state : R.State.t) depth : Z.t =
let rec random_bigint_at_depth depth : Z.t =
if depth = 0 then
Z.of_int (R.State.bits state)
Z.of_int (R.bits())
else
let depth = depth - 1 in
let prefix = random_bigint_at_depth state depth in
let suffix = random_bigint_at_depth state depth in
let prefix = random_bigint_at_depth depth in
let suffix = random_bigint_at_depth depth in
Z.(prefix lsl (bits_at_depth depth) lor suffix)
let random_value_is_uniform_in_range range depth n =
let k = Z.(range_at_depth depth / range) in
Z.lt n Z.(k * range)
let rec large_random_at_depth state range depth =
let result = random_bigint_at_depth state depth in
let rec large_random_at_depth range depth =
let result = random_bigint_at_depth depth in
if random_value_is_uniform_in_range range depth result
then Z.(result mod range)
else large_random_at_depth state range depth
else large_random_at_depth range depth
let large_random state range =
let large_random range =
let tolerance_factor = Z.of_int 1000 in
let depth = choose_bit_depth_for_range Z.(range * tolerance_factor) in
large_random_at_depth state range depth
large_random_at_depth range depth
let random state range =
let random range =
if Z.leq range Z.zero then
invalid_arg (sprintf "random: %s is not positive" (Z.to_string range))
else if Z.lt range Z.(one lsl 30) then
Z.of_int (R.State.int state (Z.to_int range))
Z.of_int (R.int (Z.to_int range))
else
large_random state range
let random range =
random (R.get_state ()) range
large_random range
end
......@@ -11,22 +11,12 @@
(** A subset of the signature of the module {!Stdlib.Random}. *)
module type S = sig
module State : sig
(** [bits s] returns 30 random bits in a nonnegative integer. *)
val bits : unit -> int
(** The state of the random number generator. *)
type t
(** [bits s] returns 30 random bits in a nonnegative integer. *)
val bits : t -> int
(** [int bound] returns a random integer comprised between 0 (inclusive)
and [bound] (exclusive). [bound] must be greater than 0 and less than
2{^30}. *)
val int : t -> int -> int
end
(** [get_state()] returns the current state of the generator. *)
val get_state : unit -> State.t
(** [int bound] returns a random integer comprised between 0 (inclusive)
and [bound] (exclusive). [bound] must be greater than 0 and less than
2{^30}. *)
val int : int -> int
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment