diff options
author | Nicklas Sindlev Andersen <nsa200293@live.dk> | 2022-06-07 19:55:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-07 18:55:57 +0100 |
commit | eeceba29e9d27fe1820bf2d806d4699a37a0469c (patch) | |
tree | d14003ab111183644e00f92b48465a379f757a5e /src | |
parent | 32d63fb1a0d8d46d17ef7077a4eb1e795dd1cc62 (diff) | |
download | gleam_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.gleam | 31 | ||||
-rw-r--r-- | src/gleam/int.gleam | 13 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 2 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 10 |
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() { |