ericmj / decimal

Arbitrary precision decimal arithmetic

Home Page:https://hexdocs.pm/decimal/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

missing pow function?

ryanhart2 opened this issue · comments

Hi,
Is there a particular reason there is no pow function similar to math.pow for Decimals?
Without this, how would you calculate x^y if x is a decimal and y is an integer?

decimal ^ integer is fairly easy, decimal ^ decimal is the tricky one and the reason we don't provide the function.

For positive integers in the exponent the algorithm would be:

Enum.reduce(1..exponent, 1, fn _, result ->
  Decimal.mult(base, result)
end)

Handling 0 and negative exponents would be fairly easy to add.

Thanks for your response! My internet searching led me to implement as below. It's a bit faster than using the Enum.reduce method, although possibly not meaningfully so in my app. The implementation below only handles integer exponents, which is okay for my use case but, I guess, not what people would be expecting from an official implementation in the Decimal library.

use Bitwise

alias Decimal

@one Decimal.new(1)

def pow(%Decimal{} = num, exp) when is_integer(exp) and exp > 1 do
  pow(@one, num, exp)
end

def pow(%Decimal{} = num, exp) when is_integer(exp) and exp < 0 do
  Decimal.div(@one, pow(@one, num, -exp))
end

def pow(%Decimal{} = _num, 0), do: @one

def pow(%Decimal{} = num, 1), do: num

defp pow(result, num, exp) when exp < 2 do
    Decimal.mult(result, num)
end

defp pow(result, num, exp) when (exp &&& 1) == 0 do
  pow(result, Decimal.mult(num, num), exp >>> 1)
end

defp pow(result, num, exp) when (exp &&& 1) == 1 do
  pow(Decimal.mult(result, num), Decimal.mult(num, num), exp >>> 1)
end

The implementation below only handles integer exponents, which is okay for my use case but, I guess, not what people would be expecting from an official implementation in the Decimal library.

Great that you already found a solution. What people would expect is an implementation of decimal ^ decimal and we don't have an algorithm for that. Contributions or proposals are appreciated.