bahaghari/lib: add more functions to math subset

This commit is contained in:
Gabriel Arazas 2024-05-29 22:56:33 +08:00
parent 1ce7fad8d5
commit 14049db2e4
No known key found for this signature in database
GPG Key ID: 62104B43D00AA360
3 changed files with 134 additions and 5 deletions

View File

@ -48,5 +48,5 @@ pkgs.lib.makeExtensible
isNumber scale;
inherit (self.hex) isHexString;
inherit (self.math) abs pow percentage;
inherit (self.math) abs pow percentage factorial round round' summate product;
})

View File

@ -4,6 +4,9 @@
{ pkgs, lib, self }:
rec {
pi = 3.141592653589793238462643383279502884197;
e = 2.7182818284590452353602874713527;
/* Returns the absolute value of the given number.
Type: abs :: Int -> Int
@ -41,6 +44,22 @@ rec {
in
if exponent < 0 then (1 / value) else value;
/* Implements the factorial function with the given value.
Type: factorial :: Number -> Number
Example:
factorial 3
=> 6
factorial 10
=> 3628800
*/
factorial = x:
assert lib.assertMsg (x >= 0)
"bahaghariLib.math.factorial: given value is not a positive integer";
product (lib.range 1 x);
/* Returns a boolean whether the given number is within the given (inclusive) range.
Type: isWithinRange :: Number -> Number -> Number -> Bool
@ -110,7 +129,7 @@ rec {
then 0
else number / (100.0 / value);
/* Given a number, round up (or down) its number to the nearest integer.
/* Given a number, round up (or down) its number to the nearest ones place.
Type: round :: Number -> Number
@ -125,9 +144,54 @@ rec {
=> 3
*/
round = number:
round' 0 number;
/* Given a tens place (10 ^ n) and a number, round the nearest integer to its
given place.
Type: round' :: Number -> Number -> Number
Example:
# Round the number to the nearest ones.
round' 0 5.65
=> 6
# Round the number to the nearest tens.
round' 1 5.65
=> 10
# Round the number to the nearest hundreds.
round' 2 5.65
=> 0
# Round the number to the nearest tenth.
round' (-1) 5.65
=> 5.7
*/
round' = tens: number:
let
number' = builtins.floor number;
difference = number - number';
nearest = pow 10.0 tens;
difference = number / nearest;
in
if difference >= 0.5 then (number' + 1) else number';
builtins.floor (difference + 0.5) * nearest;
/* Adds all of the given items on the list starting from a sum of zero.
Type: summate :: List[Number] -> Number
Example:
summate [ 1 2 3 4 ]
=> 10
*/
summate = builtins.foldl' builtins.add 0;
/* Multiply all of the given items on the list starting from a product of 1.
Type: product :: List[Number] -> Number
Example:
product [ 1 2 3 4 ]
=> 24
*/
product = builtins.foldl' builtins.mul 1;
}

View File

@ -16,6 +16,11 @@ lib.runTests {
expected = 1;
};
testsMathPowWithFloat = {
expr = self.math.pow 2 7.0;
expected = 128.0;
};
testMathAbsoluteValue = {
expr = self.math.abs 5493;
expected = 5493;
@ -86,6 +91,31 @@ lib.runTests {
expected = 3;
};
testMathRoundOnes = {
expr = self.math.round' 0 5.65;
expected = 6;
};
testMathRoundTens = {
expr = self.math.round' 1 5.65;
expected = 10;
};
testMathRoundHundreds = {
expr = self.math.round' 2 5.65;
expected = 0;
};
testMathRoundTenth = {
expr = self.math.round' (-1) 5.65;
expected = 5.7;
};
testMathRoundHundredth = {
expr = self.math.round' (-2) 5.655;
expected = 5.66;
};
testMathWithinRange = {
expr = self.math.isWithinRange (-100) 100 50;
expected = true;
@ -95,4 +125,39 @@ lib.runTests {
expr = self.math.isWithinRange 5 10 (-5);
expected = false;
};
testMathFactorial = {
expr = self.math.factorial 3;
expected = 6;
};
testMathFactorial2 = {
expr = self.math.factorial 10;
expected = 3628800;
};
testMathFactorialZero = {
expr = self.math.factorial 0;
expected = 1;
};
testMathSummate = {
expr = self.math.summate [ 1 2 3 4 ];
expected = 10;
};
testMathSummate22 = {
expr = self.math.summate [ 1 2 3 4.5 5.6 6.7 ];
expected = 22.8;
};
testMathProduct = {
expr = self.math.product [ 1 2 3 4 ];
expected = 24;
};
testMathProduct2 = {
expr = self.math.product [ 1.5 2 3 4.6 ];
expected = 41.4;
};
}