views:

3578

answers:

4

The .net framework provides in the Math class a method for powering double. But by precision requirement I need to raise a decimal to a decimal power [ Pow(decimal a, decimal b) ]. Does the framework have such a function? Does anyone know of a library with this kind of function?

A: 

Are you sure you actually want to do this? A decimal multiply is about 40 times slower than double's, so I'd expect a decimal Math.Pow() to be practically unusable.

If you expect only integer powers, though, I suggest you use the integer-based power algorithm that was already discussed here on SO.

Dmitri Nesteruk
"unusable"? Decimals raised to decimal powers are common in scientific computing (e.g., relationships between Nusselt, Reynolds, and Prandtl numbers in fluid mechanics). I doubt that it'll be a problem.
duffymo
Hardly - that would be the first time I've heard of anyone using a base-10 type like System.Decimal for scientific computations. Especially not in any area related to physics, like fluid mechanics. What is so special about these relationships that requires a base-10 type?
Christoph Rüegg
@Christoph: I'd point out that most calculators (hardware and software) use base-10 computation.
P Daddy
@duffymo: I, too, would expect a Pow(decimal, decimal) function to perform a few orders of magnitude slower than Pow(double, double), owing largely to the fact that the FPU cannot be utilized for decimals...
P Daddy
... Whether or not this would classify it as "unusable" depends on how many such calculations one expected to do in a given amount of time.
P Daddy
A: 

I think it depends a lot on the number you plan on plugging in. If 'a' and 'b' are not 'nice' number then you'll likely get a value which is non-terminating that is impossible to store and if C# BigDecimal behaves at all like Java BigDecimal it probably throws an exception in such a case.

Kevin Loney
A: 

log(c^d) = d * log(c)

further...

c^d = antilogarithm(d * log(c))

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("169^(1/2) = " + RaiseToPower((169), (.5)));
            Console.ReadLine();
        }

        public static double RaiseToPower(double a, double b)
        {
            return Math.Exp(b * Math.Log(a));
        }
    }
}
Chris Ballance
The framework provides neither Log/Ln nor Exp for System.Decimal (remember, decimal is NOT intended for scientific computations).
Christoph Rüegg
The question asked how to raise a decimal to a decimal power. No one mentioned a need for floating-point precision
Chris Ballance
The question specifically mentions "Pow(decimal a, decimal b)".
P Daddy
In what way would you say this solution is better than just using the framework's Math.Pow function? Both take doubles as input and return doubles. Neither handles System.Decimal.
norheim.se
+5  A: 

To solve my problem I found some expansion series, and them I had them implemented to solve the equation X^n = e^(n * ln x).

  // power series
  int iteration = 27; // Adjust this to modify the precision
  decimal result = 1; 
  while (iteration > 0)
  {
    fatorial = Factorial(iteration);
    result += (Pow(power, iteration) / fatorial);
    iteration--;
  }

  // natural logarithm series
  decimal aux = (value - 1);
  decimal result = 0;
  while (iteration > 0)
  {
    result += Pow(aux, iteration) / iteration;
    iteration--;
  }

The Pow() and Factorial() functions are simple because the power is always an int (inside de power series).

vappolinario