aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicklas Sindlev Andersen <nsa200293@live.dk>2022-06-07 19:55:57 +0200
committerGitHub <noreply@github.com>2022-06-07 18:55:57 +0100
commiteeceba29e9d27fe1820bf2d806d4699a37a0469c (patch)
treed14003ab111183644e00f92b48465a379f757a5e /src
parent32d63fb1a0d8d46d17ef7077a4eb1e795dd1cc62 (diff)
downloadgleam_stdlib-eeceba29e9d27fe1820bf2d806d4699a37a0469c.tar.gz
gleam_stdlib-eeceba29e9d27fe1820bf2d806d4699a37a0469c.zip
Fix int.power and float.power functions (#302)
Diffstat (limited to 'src')
-rw-r--r--src/gleam/float.gleam31
-rw-r--r--src/gleam/int.gleam13
-rw-r--r--src/gleam_stdlib.erl2
-rw-r--r--src/gleam_stdlib.mjs10
4 files changed, 37 insertions, 19 deletions
diff --git a/src/gleam/float.gleam b/src/gleam/float.gleam
index 991030c..e72eb0d 100644
--- a/src/gleam/float.gleam
+++ b/src/gleam/float.gleam
@@ -257,21 +257,33 @@ pub fn absolute_value(x: Float) -> Float {
///
/// ```gleam
/// > power(2.0, -1.0)
-/// 0.5
+/// Ok(0.5)
///
-/// ```gleam
/// > power(2.0, 2.0)
-/// 4.0
+/// Ok(4.0)
///
/// > power(8.0, 1.5)
-/// 22.627416997969522
+/// Ok(22.627416997969522)
///
/// > 4.0 |> power(of: 2.0)
-/// 16.0
+/// Ok(16.0)
+///
+/// > power(-1.0, 0.5)
+/// Error(Nil)
/// ```
///
-pub fn power(base: Float, of exponent: Float) -> Float {
- do_power(base, exponent)
+pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) {
+ let fractional: Bool = ceiling(exponent) -. exponent >. 0.
+ // In the following check:
+ // 1. If the base is negative and the exponent is fractional then
+ // return an error as it will otherwise be an imaginary number
+ // 2. If the base is 0 and the exponent is negative then the expression
+ // is equivalent to the exponent divided by 0 and an error should be
+ // returned
+ case base <. 0. && fractional || base == 0. && exponent <. 0. {
+ True -> Error(Nil)
+ False -> Ok(do_power(base, exponent))
+ }
}
if erlang {
@@ -297,10 +309,7 @@ if javascript {
/// ```
///
pub fn square_root(x: Float) -> Result(Float, Nil) {
- case x <. 0.0 {
- True -> Error(Nil)
- False -> Ok(power(x, 0.5))
- }
+ power(x, 0.5)
}
/// Returns the negative of the value provided.
diff --git a/src/gleam/int.gleam b/src/gleam/int.gleam
index 56ac399..d110c3f 100644
--- a/src/gleam/int.gleam
+++ b/src/gleam/int.gleam
@@ -27,19 +27,22 @@ pub fn absolute_value(x: Int) -> Int {
///
/// ```gleam
/// > power(2, -1.0)
-/// 0.5
+/// Ok(0.5)
///
/// > power(2, 2.0)
-/// 4
+/// Ok(4.0)
///
/// > power(8, 1.5)
-/// 22.627416997969522
+/// Ok(22.627416997969522)
///
/// > 4 |> power(of: 2.0)
-/// 16.0
+/// Ok(16.0)
+///
+/// > power(-1, 0.5)
+/// Error(Nil)
/// ```
///
-pub fn power(base: Int, of exponent: Float) -> Float {
+pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) {
base
|> to_float()
|> float.power(exponent)
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl
index 9dc769b..6fd44ed 100644
--- a/src/gleam_stdlib.erl
+++ b/src/gleam_stdlib.erl
@@ -374,4 +374,4 @@ inspect(Any) when is_function(Any) ->
),
["//fn(", Args, ") { ... }"];
inspect(Any) ->
- ["//erl(", io_lib:format("~p", [Any]), ")"].
+ ["//erl(", io_lib:format("~p", [Any]), ")"]. \ No newline at end of file
diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs
index 97fa491..b4f3d22 100644
--- a/src/gleam_stdlib.mjs
+++ b/src/gleam_stdlib.mjs
@@ -210,7 +210,7 @@ export function bit_string_to_string(bit_string) {
let decoder = new TextDecoder("utf-8", { fatal: true });
return new Ok(decoder.decode(bit_string.buffer));
} catch (_error) {
- return new Error(undefined);
+ return new Error(Nil);
}
}
@@ -239,7 +239,13 @@ export function truncate(float) {
}
export function power(base, exponent) {
- return Math.pow(base, exponent);
+ // It is checked in Gleam that:
+ // - The base is non-negative and that the exponent is not fractional.
+ // - The base is not zero and the exponent is not negative (otherwise
+ // the result will essentially be divion by zero).
+ // It can thus be assumed that valid input is passed to the Math.pow
+ // function and a NaN or Infinity value will not be produced.
+ return Math.pow(base, exponent)
}
export function random_uniform() {