Joan Venge
Joan Venge

Reputation: 331102

Why isn't there Math.Pow that takes an int as the exponent?

I read that the Math.Pow implementation is pretty complicated to be able to handle fractional powers. Why isn't there a version that takes an int for the exponent to make a faster version when you don't need fractional powers?

Upvotes: 12

Views: 3719

Answers (5)

SunsetQuest
SunsetQuest

Reputation: 8827

A decade late but I wanted to give my answer for anyone who runs across this.

I've done lots of assembly work in the past and there is usually an assembly CPU instruction (to interact with the hardware) for Pow(Double,Double) but not Pow(Double,Int). Most languages just expose this with a Pow(Double,Double) type function. There is no Pow(Double,Int) to expose to the user.

So then one can ask, why did Intel not include some hardware(aka many thousand additional transistors). I'm using Intel since they mostly were the ones who set the standard 20 years ago. Intel had limited chip realestate (transistors), and the demand for a performance mixed(mixing double/integer) instruction like that just was needed. In fact, there were not a lot of mixed instructions in general. Double tended to work with double. Float with float. Integer with Integer. There were not really many with mixed types except for instructions to convert back and forth.

Finally, I would say Pow(Double,Double) can handle Pow(Double,Int) when the Int is cast to a double is good enough. Chip makers did not use valuable chip realestate for a mixed type instruction.

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798744

Because you'd just need to convert it back into a float to multiply it against the logarithm of the base.

nm = em × ln n

Upvotes: 6

ggf31416
ggf31416

Reputation: 3647

I don't think that fast math functions was their first priority when they programmed them (see Why is Math.DivRem so inefficient). They could use a expotentiation by square that would be faster, at least for small exponents.

However because floating point is subject to rounding providing 2 different inplementations could mean different results, e.g. for pow(5.9,7) than for pow(5.9,7.0), which may be undesirable in some cases.

Upvotes: 0

Chris Gregg
Chris Gregg

Reputation: 2382

Well, you could write your own (in C):

int intPow(int a,int b){
  int answer = a;
  int i;
  for(i=0;i<b-1;i++)
    answer *= a;
  return answer;
}

Upvotes: -4

user180326
user180326

Reputation:

For a compiler it is only worthwhile to optimize by converting to a series of multiplies, if the exponent is constant. In which case you can write x*x or x*x*x yourself.

Edit: So if you want to avoid your math is done by the Math.Pow implementation (which uses exponent functions), just don't call it. If Math.Pow would be added for integers, the compiler would have figure out from how it is called if it should emit code for multiplication (if n is constant and small) or the default using exponent functions. That is non-trivial work for a compiler, and there would be no gain in terms of performance.

Upvotes: 0

Related Questions