So, I want to write a function in code using some sort of algorithm to calculate any number to any power, including decimals. I use JavaScript and it already has an inbuilt pow function:
Math.pow(2, 0.413) // 2^0.413 = 1.331451613236371, took under 1 second.
Now I want to write my own like this:
function pow(x, y) {
// Algorithm
}
This is a function that calculates the square root of any number (x^0.5), and it's very accurate with only 10 loops:
function sqrt(x, p) { // p = precision (accuracy)
var a = 1;
var b = x;
while (p--) {
a = (a + b) / 2
b = x / a
}
return a
}
Is there any simple formula to calculate any exponential?
If there isn't a simple one, is there a hard one?
If the solution is slow, how can JavaScript's pow estimate under a single second?
Those are some really nice examples, here is a simpler one too.
now call the function:
Edit: It only works on integer, but it's simple and quick.
I checked this post, but it worked only for whole numbers (1,2,3... not 0.1, 0.3...)
Recursive power function: Why does this work if there's no initial return value?
Then,
I got this from here: Algorithm for pow(float, float)
I added some basic checks (n===0)... To fasten things up in case.
Flexo sums it up:
http://mathworld.wolfram.com/NewtonsMethod.html
http://mathworld.wolfram.com/TaylorSeries.html
https://en.wikipedia.org/wiki/Logarithm#Power_series
https://rads.stackoverflow.com/amzn/click/0521431085
Heres a nice algorithm for positive integer powers, it starts by dealing with some simple cases and then uses a loop testing the binary bits of the exponent. For example to find
3^11
11 in binary is 1011 so the stages in the loop areThat is the evenPower squares at each loop, and the result gets multiplied by the evenPower if the bottom bit is 1. The code has been lifted from Patricia Shanahan’s method http://mindprod.com/jgloss/power.html which in turn has its roots in Kunth and can be traced back to 200 BC in india.
For a real exponent you will basically need ways of finding exp and log. You can use Taylor series which are the simplest to get but there are much better method. We have
To find x^y note
ln(x^y) = y*ln(x)
. Now we need to get the argument in the right range so we can use our power series. Let x = m * 2^ex, the mantissa and exponent chosen so 1/sqrt(2)<= m < sqrt(2) andln(m*2^ex) = ln(m) + ex*ln(2)
. Let h = m-1 and find ln(1+h).Using java and floats as there is an easy way to find the internals of the IEEE representation (I've used float as there are fewer bits to cope with)
in javascript it might be easiest to us Number.toExponential and parse the results.
Next construct a number z in the desired range 1/sqrt(2) < z < sqrt(2)
Use this function to find the log of 1+x using a taylor series
this seems to be good to three significant figures, often much better when x is close to 0.
The log of our number x can then be found
Now to the actual power if we write y = n + a where n is an integer and a is fractional. So
x^y=x^(n+a) = x^n * x^a
. use the first algorithm in this answer to find thex^n
. Writingx=m*2^ex
thenln((m*2^ex)^a) = yln(m) + yex*ln(2)
andthe two exponential terms have fairly small values so the taylor series should be good.
We need one function for the taylor series of the exponential function
finally we can put the pieces together
That should be the complete program, you need some smarts to cope with negative arguments etc.
Note this is not particularly accurate as I've only used a few terms of the taylor series. Other SO questions have more detailed answers How can I write a power function myself?