# Fast pow()

I’m currently working on a project that uses pow in its DSP maths, and I want to make sure it’s fast. I’ve found dsp::FastMathApproximations, but it doesn’t include pow.

https://docs.juce.com/master/structdsp_1_1FastMathApproximations.html

I’ve also found some fast approximation equations online at https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/.

The equations are

``````// 4.2 times as fast as normal pow
inline double fastPow(double a, double b) {
union {
double d;
int x[2];
} u = { a };
u.x[1] = (int)(b * (u.x[1] - 1072632447) + 1072632447);
u.x[0] = 0;
return u.d;
}
``````

~and~

``````// 3.3 times as fast as normal pow
// should be much more precise with large b
inline double fastPrecisePow(double a, double b) {
// calculate approximation with fraction of the exponent
int e = (int) b;
union {
double d;
int x[2];
} u = { a };
u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447);
u.x[0] = 0;

// exponentiation by squaring with the exponent's integer part
// double r = u.d makes everything much slower, not sure why
double r = 1.0;
while (e) {
if (e & 1) {
r *= a;
}
a *= a;
e >>= 1;
}

return r * u.d;
}
``````

Does anyone here have any experience with fast pow? What are your thoughts?

3 Likes

Well, there’s `exp()`: https://docs.juce.com/master/structdsp_1_1FastMathApproximations.html#a5b300b4425df20821f40d05669deea4b

I’l not sure what exp() is, but given it only takes one argument, I think it might be something else.

`exp(x) = e^x` and by adjusting `x` you can calculate `y^z` with help of `exp()`. So depending on your desired base or exponent, that might be useful

1 Like

Oh, neat! Unfortunately my range of values is from 0.001 to 1000, so I don’t think the -6 to +4 would be very happy about that. But I’m going to keep this in my back pocket.

I suppose you also just gave me an answer, which is that it’s probably not very likely to be using such a wide range of values.

To elaborate: `pow(x, y) = exp(ln(x) * y)`
Edit: to elaborate a little more: in case your base `x` is constant, you can calculate ´ln(x)´ once and just scale your exponent `y` with it and calculate the result using the exp approximation.

2 Likes

I’m using fmath for exp and log, it’s a little bit less precise than std, but close enough to svml everywhere AFAIK. Last time I used these to replace pow, I gain a factor of 7 between them.

I don’t know what svml is, but if it works for you, it’ll probably work for me.

Small Vector Math Library, it’s one of Intel’s fast math libraries (lesser known than MKL).

1 Like