Reputation: 331102
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
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
Reputation: 798744
Because you'd just need to convert it back into a float to multiply it against the logarithm of the base.
Upvotes: 6
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
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
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