aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinoas <mail@inoas.com>2022-04-11 23:54:33 +0200
committerLouis Pilfold <louis@lpil.uk>2022-04-16 10:23:34 +0100
commit75802b6408842e4f59521bd52e72237ef31cd64e (patch)
treebd252fffdd9816fed3e155d27925a8d62b5d1585
parentdb20f5a296038fa6ba73172eac5bd5a3818942da (diff)
downloadgleam_stdlib-75802b6408842e4f59521bd52e72237ef31cd64e.tar.gz
gleam_stdlib-75802b6408842e4f59521bd52e72237ef31cd64e.zip
wip
-rw-r--r--src/gleam/float.gleam21
-rw-r--r--src/gleam/int.gleam28
-rw-r--r--src/gleam_stdlib.mjs2
-rw-r--r--test/gleam/float_test.gleam12
-rw-r--r--test/gleam/int_test.gleam54
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)
+}