bahaghari/lib: add math.sqrt function

This commit is contained in:
Gabriel Arazas 2024-06-01 13:21:30 +08:00
parent 817ec35b02
commit 5f07c5b0fc
No known key found for this signature in database
GPG Key ID: 62104B43D00AA360
3 changed files with 59 additions and 2 deletions

View File

@ -49,5 +49,5 @@ pkgs.lib.makeExtensible
inherit (self.hex) isHexString;
inherit (self.math) abs pow percentage factorial floor ceil round round'
summate product;
summate product sqrt;
})

View File

@ -48,6 +48,41 @@ rec {
in
if exponent < 0 then (1 / value) else value;
/* Given a number, find its square root. This method is implemented using
Newton's method.
Type: sqrt :: Number -> Number
Example:
sqrt 4
=> 2
sqrt 169
=> 13
sqrt 12
=> 3.464101615
*/
sqrt = number:
assert lib.assertMsg (number >= 0)
"bahaghariLib.math.sqrt: Only positive numbers are allowed";
let
# Changing this value can change the result drastically. A value of
# 10^-13 for tolerance seems to be the most balanced so far since we are
# dealing with floats and should be enough for most cases.
tolerance = pow 10 (-13);
iter = value:
let
root = 0.5 * (value + (number / value));
in
if (abs (root - value) > tolerance) then
iter root
else
value;
in
iter number;
/* Implements the factorial function with the given value.
Type: factorial :: Number -> Number

View File

@ -166,7 +166,7 @@ lib.runTests {
expected = 10;
};
testMathSummate22 = {
testMathSummate2 = {
expr = self.math.summate [ 1 2 3 4.5 5.6 6.7 ];
expected = 22.8;
};
@ -180,4 +180,26 @@ lib.runTests {
expr = self.math.product [ 1.5 2 3 4.6 ];
expected = 41.4;
};
# All of the answers here should be sourced from another tool such as a
# calculator.
testMathSqrt = {
expr = self.math.sqrt 4;
expected = 2;
};
testMathSqrt2 = {
expr = self.math.sqrt 169;
expected = 13;
};
testMathSqrt3 = {
expr = self.math.round' (-9) (self.math.sqrt 12);
expected = 3.464101615;
};
testMathSqrt4 = {
expr = self.math.round' (-10) (self.math.sqrt 2);
expected = 1.4142135624;
};
}