In C, I was wondering whether there's an 'optimal' way to compute half-integer powers. In a nutshell, the problem is computing x^(n/2) (assuming n
is odd and decently small, and x
is a some float). Is there a major difference in performance/accuracy between sqrt(pow(x, n))
and pow(x, 0.5 * n)
? Or even reversed: pow(sqrt(x), n)
.
Is there some other implementation for handling this specific case of half-integers?
My first thought is that you would just use pow
and compute the whole thing in one call, but I feel like with floating point roundoff and things I'm losing some of the precision of the question that comes from the fact that this is explicitly a half-integer. I thought then maybe there's better error performance if you use pow
for raising to an integer power and let sqrt
handle the (1/2) part.
I also noticed that GSL has functions for computing small integer powers; would combining those functions with sqrt
be better than just using pow
?
I'm pretty new to scientific programming with C so I'm not sure where I would even go to look for implementations of something like this, and Google hasn't really turned anything up.
CodePudding user response:
Floating-point multiplication is a fairly cheap operation in typical modern processors, and multiplication of an integer by .5 introduces no rounding error when a binary-based floating-point format is used. (If the expression is written as n/2
, where n
is a floating-point type, I would expect a decent compiler to implement it as multiplication by .5. However, to be sure, it can be written as n*.5
.)
pow
is a complicated routine but its execution time1 is unlikely to be affected much by a difference between pow(x, n)
and either pow(sqrt(x), n)
or pow(x, n*.5)
. We can generally expect pow(x, n*.5)
to be a good way of computing x
n
/2.
sqrt
typically takes more execution time than floating-point multiplication and may introduce rounding error. We can expect each of sqrt(pow(x, n))
and pow(sqrt(x), n*.5)
to at least as much time as pow(x, n*.5)
, and probably more, with no benefit in accuracy.
Thus, pow(x, n*.5)
is preferred.
I also noticed that GSL has functions for computing small integer powers; would combining those functions with
sqrt
be better than just usingpow
?
Maybe. pow
is an expensive routine, so customized routines for specific powers could out-perform it, even with sqrt
added. This would be situation-dependent, and you would likely have to measure it to know.
Footnote
1 Execution time is not actually a single thing. Performing an operation not only consumes time for that operation but may affect other operations being performed in parallel in modern processors and may affect the start times of later operations, and its own start time may be affected by its relationship with prior operations.