aboutsummaryrefslogtreecommitdiff
path: root/lib/math/Calc.ex
diff options
context:
space:
mode:
authorAnhgelus Morhtuuzh <william@herges.fr>2025-11-10 11:13:40 +0100
committerAnhgelus Morhtuuzh <william@herges.fr>2025-11-10 11:13:40 +0100
commit7536cdbd312dff03ab10e46929dc1b072f881d01 (patch)
treec3f6bccc713b13be91a1cf8fff47ac1f0e8ea377 /lib/math/Calc.ex
parent244e46ed692e9d2a7c4be7c0f5adda03239ee2fd (diff)
perf(calc): use exponentiation by squaring
move calc things in new module
Diffstat (limited to 'lib/math/Calc.ex')
-rw-r--r--lib/math/Calc.ex28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/math/Calc.ex b/lib/math/Calc.ex
new file mode 100644
index 0000000..7dc5fcc
--- /dev/null
+++ b/lib/math/Calc.ex
@@ -0,0 +1,28 @@
+defmodule ElixirMathParser.Math.Calc do
+ alias ElixirMathParser.Math.Rational
+ def factorial(n), do: factorial_rec(n, 1)
+ defp factorial_rec(n, acc) when n > 0, do: factorial_rec(n - 1, acc * n)
+ defp factorial_rec(0, acc), do: acc
+
+ def pow(value, exponent), do: pow_rec(value, exponent, Rational.new(1))
+
+ defp pow_rec(value, exponent, acc) when is_integer(exponent) do
+ case exponent do
+ 0 ->
+ acc
+
+ _ when exponent < 0 ->
+ pow_rec(Rational.new(1, value), -exponent, acc)
+
+ _ when Kernel.rem(exponent, 2) == 0 ->
+ pow_rec(Rational.mult(value, value), Kernel.div(exponent, 2), acc)
+
+ _ ->
+ pow_rec(
+ Rational.mult(value, value),
+ Kernel.div(exponent - 1, 2),
+ Rational.mult(acc, value)
+ )
+ end
+ end
+end