From a170fd8344da7ca70108b34367d58aee62591876 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Sat, 15 Jun 2024 13:38:42 +0800 Subject: [PATCH] bahaghari/lib: add math.mod' function --- subprojects/bahaghari/lib/math.nix | 38 ++++++++++++++++ subprojects/bahaghari/tests/lib/math.nix | 55 ++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/subprojects/bahaghari/lib/math.nix b/subprojects/bahaghari/lib/math.nix index 63184775..8c7b5d1b 100644 --- a/subprojects/bahaghari/lib/math.nix +++ b/subprojects/bahaghari/lib/math.nix @@ -238,6 +238,44 @@ rec { in floor (difference + 0.5) * nearest; + /* Similar to the nixpkgs' `trivial.mod` but retain the decimal values. This + is just an approximation from ECMAScript's implementation of the modulo + operator (%). + + Type: mod' :: Number -> Number -> Number + + Example: + mod' 4.25 2 + => 0.25 + + mod' 1.5 2 + => 1.5 + + mod' 65 5 + => 0 + + mod' (-54) 4 + => -2 + + mod' (-54) (-4) + => -2 + */ + mod' = base: number: + let + base' = abs base; + number' = abs number; + difference = number' * ((floor base' / (floor number')) + 1); + + result = number' - (difference - base'); + in + if number' > base' then + base + else + if base < 0 then + -(result) + else + result; + /* Adds all of the given items on the list starting from a sum of zero. Type: summate :: List[Number] -> Number diff --git a/subprojects/bahaghari/tests/lib/math.nix b/subprojects/bahaghari/tests/lib/math.nix index 50cf1f07..f3710deb 100644 --- a/subprojects/bahaghari/tests/lib/math.nix +++ b/subprojects/bahaghari/tests/lib/math.nix @@ -212,6 +212,61 @@ lib.runTests { expected = 1.4142135624; }; + testMathMod = { + expr = self.math.mod' 65.5 3; + expected = 2.5; + }; + + testMathMod2 = { + expr = self.math.mod' 1.5 3; + expected = 1.5; + }; + + testMathMod3 = { + expr = self.math.mod' 4.25 2; + expected = 0.25; + }; + + testMathMod4 = { + expr = self.math.mod' 6 6; + expected = 0; + }; + + testMathMod5 = { + expr = self.math.mod' 6.5 6; + expected = 0.5; + }; + + testMathMod6 = { + expr = self.math.mod' 7856.5 20; + expected = 16.5; + }; + + testMathMod7 = { + expr = self.math.mod' 7568639.2 45633; + expected = 39194.200000000186; + }; + + testMathModBothPositive = { + expr = self.math.mod' 54.5 20.5; + expected = 13.5; + }; + + testMathModNegativeBase = { + expr = self.math.mod' (-54.5) 20.5; + expected = -13.5; + }; + + testMathModNegativeNumber = { + expr = self.math.mod' 54.5 (-20.5); + expected = 13.5; + }; + + testMathModBothNegatives = { + expr = self.math.mod' (-54.5) (-20.5); + expected = -13.5; + }; + testMathExp = { expr = self.math.exp 1; expected = 2.7182818284590452353602874713527;