Work on the float module

This commit is contained in:
NicklasXYZ 2023-01-08 22:14:06 +01:00
parent 20d2a01f31
commit 6ddeddac19
4 changed files with 118 additions and 63 deletions

View file

@ -29,7 +29,7 @@ pub fn main() {
// Returns Tuple: Ok(#(3.0, 50.0))
// Find the list indices of the largest values
int_list.argmax([10, 3, 50, 20, 3])
int_list.arg_maximum([10, 3, 50, 20, 3])
// Returns List: Ok([1, 4])
}

View file

@ -1573,19 +1573,30 @@ if erlang {
/// </a>
/// </div>
///
/// The function rounds a floating point number to a specific decimal precision using a given rounding mode.
/// The function rounds a floating point number to a specific number of digits using a given rounding mode.
///
/// Valid rounding modes include:
/// - `Nearest` (default): If the last digit is equal to 5, then the previous digit is rounded to nearest even integer value.
/// - An alias for this rounding mode is [`truncate`](#truncate)
/// - `TiesAway`: If the last digit is equal to 5, then the previous digit is rounded away from zero (C/C++ rounding behavior).
/// - `TiesUp`: If the last digit is equal to 5, then the previous digit is rounded towards $$+\infty$$ (Java/JavaScript rounding behaviour).
/// - `ToZero`: If the last digit is equal to 5, then the previous digit is rounded towards $$0$$.
/// - `ToZero`: The last digit is rounded towards $$0$$.
/// - An alias for this rounding mode is [`truncate`](#truncate)
/// - `Down`: If the last digit larger than 0, then the previous digit is rounded towards $$-\infty$$.
/// - An alias for this rounding mode is [`floor`](#floor)
/// - `Up`: If the last digit is larger than 0, then the previous digit is rounded towards $$+\infty$$.
/// - An alias for this rounding mode is [`ceiling`](#ceiling)
///
/// Valid rounding modes include:
/// - `Nearest` (default): The specified digit is rounded to nearest even integer value if the following digit + 1 is equal to 5.
/// - `TiesAway`: The specified digit is rounded away from zero (C/C++ rounding behavior) if the following digit + 1 is equal to 5.
/// - `TiesUp`: The specified digit is rounded towards $$+\infty$$ (Java/JavaScript rounding behaviour) if the following digit + 1 is equal to 5.
/// - `ToZero`: The input value is truncated at the specified digit.
/// - An alias for this rounding mode is [`truncate`](#truncate)
/// - `Down`: The specified digit is rounded towards $$-\infty$$ if the following digit + 1 is larger than 0.
/// - An alias for this rounding mode is [`floor`](#floor)
/// - `Up`: The specified digit is rounded towards $$+\infty$$ if the following digit + 1 is larger than 0.
/// - An alias for this rounding mode is [`ceiling`](#ceiling)
///
/// <details>
/// <summary>Example:</summary>
///
@ -1763,10 +1774,8 @@ if erlang {
/// </a>
/// </div>
///
pub fn truncate(x: Float, precision: Int) -> Float {
todo
// assert Ok(p) = power(10.0, int.to_float(precision))
// int.to_float(float.round(x *. p)) /. p
pub fn truncate(x: Float, digits: Int) -> Result(Float, String) {
round(x, option.Some(digits), option.Some("ToZero"))
}
/// <div style="text-align: right;">

View file

@ -22,29 +22,27 @@
//// A module containing several different kinds of mathematical functions
//// applying to integer numbers.
////
//// Function naming has been adopted from <a href="https://en.wikipedia.org/wiki/C_mathematical_functions"> C mathematical function</a>.
////
//// ---
////
//// * **Sign and absolute value functions**
//// * [`abs2`](#abs2)
//// * [`absdiff`](#abs_diff)
//// * [`absolute_difference`](#absolute_difference)
//// * [`sign`](#sign)
//// * [`copysign`](#copysign)
//// * [`flipsign`](#flipsign)
//// * [`copy_sign`](#copysign)
//// * [`flip_sign`](#flipsign)
//// * **Powers, logs and roots**
//// * [`exp`](#exp)
//// * [`ln`](#ln)
//// * [`log`](#log)
//// * [`log10`](#log10)
//// * [`log2`](#log2)
//// * [`pow`](#pow)
//// * [`sqrt`](#sqrt)
//// * [`cbrt`](#cbrt)
//// * [`hypot`](#hypot)
//// * [`exponential`](#exp)
//// * [`natural_logarithm`](#ln)
//// * [`logarithm`](#logarithm)
//// * [`logarithm_10`](#logarithm_10)
//// * [`logarithm_2`](#logarithm_2)
//// * [`power`](#power)
//// * [`square_root`](#square_root)
//// * [`cube_root`](#cube_root)
//// * [`nth_root`](#nth_root)
//// * [`hypotenuse`](#hypotenuse)
//// * **Misc. mathematical functions**
//// * [`min`](#min)
//// * [`max`](#max)
//// * [`minimum`](#min)
//// * [`maxximum`](#max)
//// * [`minmax`](#minmax)
//// * **Division functions**
//// * [`gcd`](#gcd)
@ -54,15 +52,18 @@
//// * [`factorial`](#factorial)
//// * [`permutation`](#permutation)
//// * **Tests**
//// * [`ispow2`](#ispow2)
//// * [`iseven`](#iseven)
//// * [`isodd`](#isodd)
//// * [`is_power`](#is_power_of)
//// * [`is_even`](#is_even)
//// * [`is_odd`](#isodd)
//// * **Misc. functions**
//// * [`to_float`](#to_float)
import gleam/list
import gleam/int
import gleam/float
import gleam/io
import gleam/option
import gleam_community/maths/float as floatx
/// <div style="text-align: right;">
/// <a href="https://github.com/gleam-community/maths/issues">
@ -79,10 +80,10 @@ import gleam/float
/// import gleam_stats/math
///
/// pub fn example() {
/// math.min(2.0, 1.5)
/// math.minimum(2.0, 1.5)
/// |> should.equal(1.5)
///
/// math.min(1.5, 2.0)
/// math.minimum(1.5, 2.0)
/// |> should.equal(1.5)
/// }
/// </details>
@ -93,7 +94,7 @@ import gleam/float
/// </a>
/// </div>
///
pub fn min(x: Int, y: Int) -> Int {
pub fn minimum(x: Int, y: Int) -> Int {
case x < y {
True -> x
False -> y
@ -106,7 +107,7 @@ pub fn min(x: Int, y: Int) -> Int {
/// </a>
/// </div>
///
/// The min function.
/// The maximum function.
///
/// <details>
/// <summary>Example:</summary>
@ -115,10 +116,10 @@ pub fn min(x: Int, y: Int) -> Int {
/// import gleam_stats/math
///
/// pub fn example() {
/// math.min(2.0, 1.5)
/// math.maximum(2.0, 1.5)
/// |> should.equal(1.5)
///
/// math.min(1.5, 2.0)
/// math.maximum(1.5, 2.0)
/// |> should.equal(1.5)
/// }
/// </details>
@ -129,7 +130,7 @@ pub fn min(x: Int, y: Int) -> Int {
/// </a>
/// </div>
///
pub fn max(x: Int, y: Int) -> Int {
pub fn maximum(x: Int, y: Int) -> Int {
case x > y {
True -> x
False -> y
@ -166,7 +167,7 @@ pub fn max(x: Int, y: Int) -> Int {
/// </div>
///
pub fn minmax(x: Int, y: Int) -> #(Int, Int) {
#(min(x, y), max(x, y))
#(minimum(x, y), maximum(x, y))
}
/// <div style="text-align: right;">
@ -219,7 +220,7 @@ if javascript {
/// </a>
/// </div>
///
pub fn flipsign(x: Int) -> Int {
pub fn flip_sign(x: Int) -> Int {
-1 * x
}
@ -452,10 +453,10 @@ pub fn permutation(n: Int, k: Int) -> Result(Int, String) {
/// import gleam_stats/math
///
/// pub fn example() {
/// math.absdiff(-10.0, 10.0)
/// math.absolute_difference(-10.0, 10.0)
/// |> should.equal(20.0)
///
/// math.absdiff(0.0, -2.0)
/// math.absolute_difference(0.0, -2.0)
/// |> should.equal(2.0)
/// }
/// </details>
@ -466,7 +467,38 @@ pub fn permutation(n: Int, k: Int) -> Result(Int, String) {
/// </a>
/// </div>
///
pub fn absdiff(a: Int, b: Int) -> Int {
pub fn absolute_difference(a: Int, b: Int) -> Int {
a - b
|> int.absolute_value()
}
/// <div style="text-align: right;">
/// <a href="https://github.com/gleam-community/maths/issues">
/// <small>Spot a typo? Open an issue!</small>
/// </a>
/// </div>
///
/// <details>
/// <summary>Example:</summary>
///
/// import gleeunit/should
/// import gleam_stats/math
///
/// pub fn example() {
///
/// }
/// </details>
///
/// <div style="text-align: right;">
/// <a href="#">
/// <small>Back to top </small>
/// </a>
/// </div>
///
pub fn is_power(x: Int, y: Int) -> Bool {
assert Ok(value) =
floatx.logarithm(int.to_float(x), option.Some(int.to_float(y)))
assert Ok(truncated) = floatx.truncate(value, 0)
let rem = value -. truncated
rem == 0.0
}

View file

@ -4,29 +4,29 @@ import gleeunit/should
import gleam/result
import gleam/io
pub fn int_absdiff_test() {
intx.absdiff(0, 0)
pub fn int_absolute_difference_test() {
intx.absolute_difference(0, 0)
|> should.equal(0)
intx.absdiff(1, 2)
intx.absolute_difference(1, 2)
|> should.equal(1)
intx.absdiff(2, 1)
intx.absolute_difference(2, 1)
|> should.equal(1)
intx.absdiff(-1, 0)
intx.absolute_difference(-1, 0)
|> should.equal(1)
intx.absdiff(0, -1)
intx.absolute_difference(0, -1)
|> should.equal(1)
intx.absdiff(10, 20)
intx.absolute_difference(10, 20)
|> should.equal(10)
intx.absdiff(-10, -20)
intx.absolute_difference(-10, -20)
|> should.equal(10)
intx.absdiff(-10, 10)
intx.absolute_difference(-10, 10)
|> should.equal(20)
}
@ -92,31 +92,31 @@ pub fn math_permutation_test() {
|> should.equal(Ok(12))
}
pub fn float_min_test() {
intx.min(75, 50)
pub fn float_minimum_test() {
intx.minimum(75, 50)
|> should.equal(50)
intx.min(50, 75)
intx.minimum(50, 75)
|> should.equal(50)
intx.min(-75, 50)
intx.minimum(-75, 50)
|> should.equal(-75)
intx.min(-75, 50)
intx.minimum(-75, 50)
|> should.equal(-75)
}
pub fn float_max_test() {
intx.max(75, 50)
pub fn float_maximum_test() {
intx.maximum(75, 50)
|> should.equal(75)
intx.max(50, 75)
intx.maximum(50, 75)
|> should.equal(75)
intx.max(-75, 50)
intx.maximum(-75, 50)
|> should.equal(50)
intx.max(-75, 50)
intx.maximum(-75, 50)
|> should.equal(50)
}
@ -145,13 +145,27 @@ pub fn int_sign_test() {
|> should.equal(-1)
}
pub fn int_flipsign_test() {
intx.flipsign(100)
pub fn int_flip_sign_test() {
intx.flip_sign(100)
|> should.equal(-100)
intx.flipsign(0)
intx.flip_sign(0)
|> should.equal(-0)
intx.flipsign(-100)
intx.flip_sign(-100)
|> should.equal(100)
}
pub fn int_is_power_test() {
intx.is_power(10, 10)
|> should.equal(True)
intx.is_power(11, 10)
|> should.equal(False)
intx.is_power(4, 2)
|> should.equal(True)
intx.is_power(5, 2)
|> should.equal(False)
}