diff options
-rw-r--r-- | src/gleam/float.gleam | 21 | ||||
-rw-r--r-- | src/gleam/int.gleam | 28 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 2 | ||||
-rw-r--r-- | test/gleam/float_test.gleam | 12 | ||||
-rw-r--r-- | test/gleam/int_test.gleam | 54 |
5 files changed, 103 insertions, 14 deletions
diff --git a/src/gleam/float.gleam b/src/gleam/float.gleam index 4c314a9..20fd6c8 100644 --- a/src/gleam/float.gleam +++ b/src/gleam/float.gleam @@ -321,10 +321,11 @@ fn do_product(numbers: List(Float), initial: Float) -> Float { } } -/// Returns a random value where 0.0 =< value < 1.0 +/// Returns a uniform random number +/// Thus where 0.0 =< value < 1.0 /// -pub fn random() -> Float { - do_random() +pub fn random_uniform() -> Float { + do_random_uniform() } if erlang { @@ -332,7 +333,7 @@ if erlang { // 0.0 =< X < 1.0 and updates the state in the process dictionary. /// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> /// - external fn do_random() -> Float = + external fn do_random_uniform() -> Float = "rand" "uniform" } @@ -344,6 +345,14 @@ if javascript { /// Note that as numbers in JavaScript are IEEE 754 floating point numbers /// See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> /// - external fn do_random() -> Float = - "../gleam_stdlib.mjs" "random" + external fn do_random_uniform() -> Float = + "../gleam_stdlib.mjs" "random_uniform" +} + +pub fn random_between(min: Float, max: Float) -> Float { + // ```javascript + // return Math.floor(Math.random() * (max - min + 1) + min); // The maximum is/shuould-be exclusive + // ``` + // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values> + random_uniform() *. { max -. min } +. min } diff --git a/src/gleam/int.gleam b/src/gleam/int.gleam index c60affb..9da5c97 100644 --- a/src/gleam/int.gleam +++ b/src/gleam/int.gleam @@ -1,4 +1,6 @@ import gleam/order.{Order} +// import gleam/float.{floor, parse, random} +import gleam/float /// Returns the absolute value of the input. /// @@ -324,7 +326,7 @@ fn do_product(numbers: List(Int), initial: Int) -> Int { } } -/// Splits an integer into its digit representation in the specified base +/// Splits an integer into its digit representation in the specified base /// /// ## Examples /// @@ -380,3 +382,27 @@ fn do_undigits( [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) } } + +pub fn random_below(max: Int) -> Int { + // ```javascript + // return Math.floor(rand * max); + // ``` + // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> + float.random_uniform() *. to_float(max) + |> float.floor() + |> float.round() + // Does `float.round() `affect random distribution uniformity? +} + +pub fn random_between(min: Int, max: Int) -> Int { + // ```javascript + // min = Math.ceil(min); + // max = Math.floor(max); + // return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is + // ``` + // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values> + float.random_between(to_float(min), to_float(max)) + |> float.floor() + |> float.round() + // Does float.round() affect random distribution uniformity? +} diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs index 5d80640..59077e9 100644 --- a/src/gleam_stdlib.mjs +++ b/src/gleam_stdlib.mjs @@ -246,7 +246,7 @@ export function power(base, exponent) { return Math.pow(base, exponent); } -export function random() { +export function random_uniform() { return Math.random(); } diff --git a/test/gleam/float_test.gleam b/test/gleam/float_test.gleam index 4236bbd..c043741 100644 --- a/test/gleam/float_test.gleam +++ b/test/gleam/float_test.gleam @@ -302,17 +302,17 @@ pub fn product_test() { } pub fn random_lower_boundary_test() { - { float.random() >=. 0. } + { float.random_uniform() >=. 0. } |> should.be_true() - { float.random() <. 0. } + { float.random_uniform() <. 0. } |> should.be_false() } if erlang { pub fn random_upper_boundary_test() { - { float.random() <. 1. } + { float.random_uniform() <. 1. } |> should.be_true() - { float.random() >=. 1. } + { float.random_uniform() >=. 1. } |> should.be_false() } } @@ -321,9 +321,9 @@ if javascript { // Due to IEEE 754 floating point numbers // the ceiling may be rounded to 1.0 even if it should not pub fn random_upper_boundary_test() { - { float.random() <=. 1. } + { float.random_uniform() <=. 1. } |> should.be_true() - { float.random() >. 1. } + { float.random_uniform() >. 1. } |> should.be_false() } } diff --git a/test/gleam/int_test.gleam b/test/gleam/int_test.gleam index 1fbc102..90b573e 100644 --- a/test/gleam/int_test.gleam +++ b/test/gleam/int_test.gleam @@ -1,6 +1,8 @@ import gleam/should import gleam/int import gleam/order +import gleam/list +import gleam/iterator.{repeat} pub fn absolute_value_test() { 123 @@ -316,3 +318,55 @@ pub fn undigits_test() { int.undigits([1, 1, 2], 2) |> should.equal(Error(int.InvalidBase)) } + +pub fn random_below_test() { + let do_random_below_test = fn(_acc, _e) { + int.random_below(0) + |> should.equal(0) + + int.random_below(-1) + |> list.contains([-1], _) + |> should.be_true + + int.random_below(1) + |> list.contains([0], _) + |> should.be_true + + int.random_below(2) + |> list.contains([0, 1], _) + |> should.be_true + + int.random_below(3) + |> list.contains([0, 1, 2], _) + |> should.be_true + + int.random_below(4) + |> list.contains([0, 1, 2, 3], _) + |> should.be_true + } + list.range(0, 100) + |> iterator.from_list + |> iterator.fold(Nil, do_random_below_test) +} + +pub fn random_between_test() { + let do_random_between_test = fn(_acc, _e) { + int.random_between(0, 0) + |> should.equal(0) + + int.random_between(-1, 0) + |> list.contains([-1, 0], _) + |> should.be_true + + int.random_between(-1, 1) + |> list.contains([-1, 0], _) + |> should.be_true + + int.random_between(-1, 2) + |> list.contains([-1, 0, 1], _) + |> should.be_true + } + list.range(0, 100) + |> iterator.from_list + |> iterator.fold(Nil, do_random_between_test) +} |