aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/float.gleam13
-rw-r--r--src/gleam/int.gleam28
-rw-r--r--src/gleam_stdlib.mjs13
3 files changed, 30 insertions, 24 deletions
diff --git a/src/gleam/float.gleam b/src/gleam/float.gleam
index 1b8220b..d41bc21 100644
--- a/src/gleam/float.gleam
+++ b/src/gleam/float.gleam
@@ -338,22 +338,19 @@ if erlang {
}
if javascript {
- /// With round-to-nearest-even behavior, the ranges claimed for the functions below
- /// (excluding the one for Math.random() itself) aren't exact.
- /// If extremely large bounds are chosen (2^53 or higher),
- /// it's possible in extremely rare cases to calculate the usually-excluded upper bound.
- /// 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_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/should-be exclusive
+ // return Math.random() * (max - min) + min; // The minimum is inclusive and the maximum is 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
}
+
+pub fn random_below(max: Float) -> Float {
+ random_uniform() *. max
+}
diff --git a/src/gleam/int.gleam b/src/gleam/int.gleam
index c255dd0..06ad12c 100644
--- a/src/gleam/int.gleam
+++ b/src/gleam/int.gleam
@@ -1,5 +1,4 @@
import gleam/order.{Order}
-// import gleam/float.{floor, parse, random}
import gleam/float
/// Returns the absolute value of the input.
@@ -383,26 +382,25 @@ fn do_undigits(
}
}
-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()
- // TODO: 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 inclusive and the minimum is inclusive
+ // return Math.floor(Math.random() * (max - min) + min); // The minimum is inclusive and the maximum is exclusive
// ```
// 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))
+ let min =
+ to_float(min)
+ |> float.ceiling()
+ let max =
+ to_float(max)
+ |> float.floor()
+
+ float.random_between(min, max)
|> float.floor()
|> float.round()
- // TODO: Does float.round() affect random distribution uniformity?
+}
+
+pub fn random_below(max: Int) -> Int {
+ random_between(0, max)
}
diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs
index 59077e9..6604bff 100644
--- a/src/gleam_stdlib.mjs
+++ b/src/gleam_stdlib.mjs
@@ -247,7 +247,18 @@ export function power(base, exponent) {
}
export function random_uniform() {
- return Math.random();
+ let random_uniform_result = Math.random();
+ // With round-to-nearest-even behavior, the ranges claimed for the functions below
+ // (excluding the one for Math.random() itself) aren't exact.
+ // If extremely large bounds are chosen (2^53 or higher),
+ // it's possible in extremely rare cases to calculate the usually-excluded upper bound.
+ // 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>
+ // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0:
+ if (random_uniform_result === 1.0) {
+ return random_uniform();
+ }
+ return random_uniform_result;
}
export function bit_string_slice(bits, position, length) {