quagmt / udecimal

A high-performance, high precision, zero allocation fixed-point decimal library for financial applications
https://quagmt.github.io/udecimal/
BSD 3-Clause "New" or "Revised" License
111 stars 4 forks source link

Pow 0 to 0 should be 1 or error #25

Closed matejsp closed 2 days ago

matejsp commented 4 days ago

One interesting edge case is what is the value of: 0^0. It can be only 1 or undefined ... https://www.cuemath.com/questions/what-is-0-to-the-0-power/

udecimal returns 0 (I see comment but I don't understand why avoid 1?): https://github.com/quagmt/udecimal/blob/master/decimal.go#L1151

print(udecimal.Zero.PowInt(0).String())

Returns 1: https://github.com/govalues/decimal/blob/main/decimal.go#L1270

Returns error https://github.com/shopspring/decimal/blob/master/decimal.go#L861

quagmt commented 3 days ago

Because 0^0 and 0.Pow(negaive integer) are undefined, I want to make the behavior consistent: zero pow any number will return 0. Also from my experience, this is what I usually do (and I think some people will do the same):

func calcSomething(a decimal, e int) decimal {
      if a.IsZero() {
            // return 0 immediately if the input number is 0
           return Zero
      }

     // caclulate pow
     a.Pow(e)
     ...
    // continue with other calculations
     ...
}

I agree that the approach doesn't follow the standard as you mentioned. However the PowInt function only return decimal. To fix this, I'm thinking of deprecating the PowInt function and replace it by PowInt32(e int32) (decimal,error) to handle 0^0 and 0 pow negative correctly.