aboutsummaryrefslogtreecommitdiff
path: root/lib/math/Calc.ex
blob: 7dc5fcc5d9e2d4f3009c8fcaad951242052acb77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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