I am having a problem trying to solve an equation in programming.
Imagine I have this line of code:
Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10;
Given x = 1000, the result is 320.
Now, how can I solve this equation given a result?
Imagine given the result 320 I want to get the minimum integer value of x that resolves that line of code.
/*320 =*/ Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10;
I am having some hard time because of the Math.Round. Even thought that expression is a linear equation, the Math.Round makes way more solutions than one for x, so I want the minimum integer value for my solution.
Note that x is a integer and if I set x = 999 the result is still 320.
If I keep lowering x I can see that 984 (atleast in Chrome 64.0.3282.186) is the correct answer in this case, because is the lowest value of x equals to 320 in that expression/programming line.
Solving the equation with the Math.round just introduces boundary conditions.
If:
Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10 = 320
Then:
Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) = 32
By dividing both sides by 10. Now you have:
Math.round(expression) = 32
Which can be expressed as an inequality statement:
31.5 < expression < 32.4999..
The expression being equal to 31.5 represents one boundary, and the expression being equal to 32.499.. represents the other boundary.So solving for the boundaries would require solving for:
expression = 31.5 and expression = 32.49999...
((x / 5) + Math.pow(x / 25, 1.3))/10 = 31.5 and
((x / 5) + Math.pow(x / 25, 1.3))/10 = 32.4999
Solving these two for x will give you the range of valid values for x. Now that's just algebra which I'm not going to do :)
I guess the most reliable way that works (albeit somewhat naive) is to loop through all valid numbers and check the predicate.
function getMinimumIntegerSolution(func, expectedResult){
for(let i = 0 /*Or Number.MIN_SAFE_INTEGER for -ves*/; i< Number.MAX_SAFE_INTEGER ; i++ ) {
if(func(i) === expectedResult)
return i;
}
}
Now
getMinimumIntegerSolution((x) => Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10 , 320)
This returns what you expect, 984
Because the function defined by
f(n) = Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10
is monotonous (in this case, increasing), you can do a binary search.
Note that I wrote the following code originally in Java, and it is syntactically incorrect in Javascript, but should hopefully be straightforward to translate into the latter.
var x0 = 0;
var x1 = 1e6;
var Y = 320d;
var epsilon = 10d;
var x = (x1 - x0) / 2d;
var y = 0;
while (Math.abs(Y - (y = f(x))) > epsilon) {
if (y > Y) {
x = (x - x0) / 2d;
} else {
x = (x1 - x) / 2d;
}
// System.out.println(y + " " + x);
}
while (f(x) < Y)
++x;
// System.out.println(Math.round(x) + " " + f(x));
Running it on my computer leaving the System.out.println uncommented:
490250.0 250000.0
208490.0 125000.0
89370.0 62500.0
38640.0 31250.0
16870.0 15625.0
7440.0 7812.5
3310.0 3906.25
1490.0 1953.125
680.0 976.5625
984 320.0
Note that the last loop incrementing x is guaranteed to complete in less than epsilon steps.
The values of x0, x1 and epsilon can be tweaked to provide better bounds for your problem.
This algorithm will fail if the value of epsilon is "too small", because of the rounding happening in f.
The complexity of this solution is O(log2(x1 - x0)).
In addition to #webnetweaver answer. If you rearrange the final equation you get a high-order polynomial (13th degree) which is difficult to solve algebraically. You can use numerical methods as Newton's method. For numerical methods in JavaScript you can use numeric.js. You also need to solve only for the lower bound (31.5) in order to find the lowest integer x because the function is monotonic increasing. See also this post on numerical equation solving in JavaScript.
Here is a solution using Newton's method. It uses 0 as initial guess. It only takes five iterations for getting the minimum integer solution.
var result = 320;
var d = result - 5;
function func(x) {
return x / 5 + 0.0152292 * Math.pow(x, 1.3) - d;
}
function deriv(x) {
return 0.2 + 0.019798 * Math.pow(x, 0.3);
}
var epsilon = 0.001; //termination condition
function newton(guess) {
var approx = guess - func(guess) / deriv(guess);
if (Math.abs(guess - approx) > epsilon) {
console.log("Guess: " + guess);
return newton(approx);
} else {
//round solution up for minimum integer
return Math.ceil(approx);
}
}
console.log("Minimum integer: " + newton(0));
Related
For an odds calculator for a board game, I need to calculate how many rounds a battle will last on average. Because there is a possibility that both sides in the battle will miss, a battle can theoretically last forever. Therefore I cannot traverse all branches, but need to calculate a mathematical limit. By verifying with a simulator, I have found that the following function correctly approximates the average number of rounds left:
// LIMIT could be any number, the larger it is, the more accurate the result.
const LIMIT = 100;
// r is the number of rounds left if at least 1 of the sides hit
// x is the chance that both sides miss and the round count gets increased,
// but the battle state stays the same.
function approximateLimitForNumberOfRounds(r: number, x: number) {
let approx = r / (1 - x);
// n -> infinity
for (let n = 1; n < LIMIT; n++) {
approx += x ** n;
}
return approx;
}
How can I modify this function to exactly calculate the number of rounds left, instead of approximating it? (noting that since x is a chance, it is contained in (0, 1) or 0 < x < 1).
We can note that approx takes on the following values:
r / (1 - x) # I refer to this as 'a' below
a + x
a + x + x^2
a + x + x^2 + x^3
a + x + x^2 + ... + x^n
Thus, we can simplify the mathematical expression to be:
a + (the sum of x^k from k = 1 to k = n)
Next, we must note that the sequence x + x^2 + x^3 ... forms a geometric sequence with first term x and common ratio x. Since x is bounded by 0 < x < 1, this will have a limiting sum, namely:
x + x^2 + x^3 + ... x^inf = x/(1-x)
(this obviously fails when x = 1, as well as in the original function where r / (1 - x) is taken, but in that case, you will simply have the sum as infinity and approx would escape to infinity if it were not undefined; so I am assuming that x != 1 in the following calculations and x = 1 can be / has been dealt with separately).
Now, since we have both a single expression for x + x^2 + ... to infinity, and a single expression for approx that includes x + x^2 + ... then we can write approx using both of these two facts:
approx = r / (1 - x) + x / (1 - x)
approx = (r + x) / (1 - x)
And there you go! That is the mathematical equivalent of the logic you've outlined in your question, compressed to a single statement (which I believe is correct :)).
Let's say you have a function that takes both x and y, real numbers that are integers, as arguments.
What would you put inside that function, using only mathematical operators, so that no two given sequences of arguments could ever return the same value, be it any kind of value?
Example of a function that fails at doing this:
function myfunction(x,y){
return x * y;
}
// myfunction(2,6) and myfunction(3,4) will both return 12
// myfunction(2,6) and myfunction(6,2) also both return 12.
As already noted in comments, at the level of JavaScript numbers such a function can't exist, simply because assuming that we're working with integer-valued IEEE 754 binary64 floats there are more possible input pairs than possible output values.
But to the mathematical question of whether there is a simple, injective function from pairs of integers to a single integer, the answer is yes. Here's one such function that uses only addition and multiplication, so should fit the questioner's "using only mathematical operators" constraint.
First we map each of the inputs from the domain of integers to the domain of nonnegative integers. The polynomial map x ↦ 2*x*x + x will do that for us, and maps distinct values to distinct values. (Sketch of proof: if 2*x*x + x == 2*y*y + y for some integers x and y, then rearranging and factoring gives (x - y) * (2*x + 2*y + 1) == 0; the second factor can never be zero for integers x and y, so the first factor must be zero and x == y.)
Second, given a pair of nonnegative integers (a, b), we map that pair to a single (nonnegative) integer using (a, b) ↦ (a + b)*(a + b) + a. It's easy to see that this, too, is injective: given the value of (a + b)*(a + b) + a, I can recover the value of a + b by taking the integer square root, and from there recover a and b.
Here's some Python code demonstrating the above:
def encode_pair(x, y):
""" Encode a pair of integers as a single (nonnegative) integer. """
a = 2*x*x + x
b = 2*y*y + y
return (a + b)*(a + b) + a
We can easily check that there are no repetitions for small x and y: here we take all pairs (x, y) with -500 <= x < 500 and -500 <= y < 500, and find the set containing encode_pair(x, y) for each combination. If all goes well, we should end up with a set with exactly 1 million entries, one per input combination.
>>> all_outputs = {encode_pair(x, y) for x in range(-500, 500) for y in range(-500, 500)}
>>> len(all_outputs)
1000000
>>> min(all_outputs)
0
But perhaps a more convincing way to establish the injectivity is to give an explicit inverse, showing that the original (x, y) can be recovered from the output. Here's that inverse function. It makes use of Python's integer square root operation math.isqrt, which is available only for Python >= 3.8, but is easy to implement yourself if you need it.
from math import isqrt
def decode_pair(n):
""" Decode an integer produced by encode_pair. """
a_plus_b = isqrt(n)
a = n - a_plus_b*a_plus_b
b = a_plus_b - a
c = isqrt(8*a + 1)
d = isqrt(8*b + 1)
return ((2 - c%4) * c - 1) // 4, ((2 - d%4) * d - 1) // 4
Example usage:
>>> encode_pair(3, 7)
15897
>>> decode_pair(15897)
(3, 7)
Depending on what you allow as a "mathematical operator" (which isn't really a particularly well-defined term), there are tighter functions possible. Here's a variant of the above that provides not just an injection but a bijection: every integer appears as the encoding of some pair of integers. It extends the set of mathematical operators used to include subtraction, division and absolute value. (Note that all divisions appearing in encode_pair are exact integer divisions, without any remainder.)
def encode_pair(x, y):
""" Encode a pair of integers as a single integer.
This gives a bijective map Z x Z -> Z.
"""
ax = (abs(2 * x + 1) - 1) // 2 # x if x >= 0, -1-x if x < 0
sx = (ax - x) // (2 * ax + 1) # 0 if x >= 0, 1 if x < 0
ay = (abs(2 * y + 1) - 1) // 2 # y if y >= 0, -1-y if y < 0
sy = (ay - y) // (2 * ay + 1) # 0 if y >= 0, 1 if y < 0
xy = (ax + ay + 1) * (ax + ay) // 2 + ax # encode ax and ay as xy
an = 2 * xy + sx # encode xy and sx as an
n = an - (2 * an + 1) * sy # encode an and sy as n
return n
def decode_pair(n):
""" Inverse of encode_pair. """
# decode an and sy from n
an = (abs(2 * n + 1) - 1) // 2
sy = (an - n) // (2 * an + 1)
# decode xy and sx from an
sx = an % 2
xy = an // 2
# decode ax and ay from xy
ax_plus_ay = (isqrt(8 * xy + 1) - 1) // 2
ax = xy - ax_plus_ay * (ax_plus_ay + 1) // 2
ay = ax_plus_ay - ax
# recover x from ax and sx, and y from ay and sy
x = ax - (1 + 2 * ax) * sx
y = ay - (1 + 2 * ay) * sy
return x, y
And now every integer appears as the encoding of exactly one pair, so we can start with an arbitrary integer, decode it to a pair, and re-encode to recover the same integer:
>>> n = -12345
>>> decode_pair(n)
(67, -44)
>>> encode_pair(67, -44)
-12345
The encode_pair function above is deliberately quite verbose, in order to explain all the steps involved. But the code and the algebra can be simplified: here's exactly the same computation expressed more compactly.
def encode_pair_cryptic(x, y):
""" Encode a pair of integers as a single integer.
This gives a bijective map Z x Z -> Z.
"""
c = abs(2 * x + 1)
d = abs(2 * y + 1)
e = (2 * y + 1) * ((c + d)**2 * c + 2 * (c - d) * c - 4 * x - 2)
return (e - 2 * c * d) // (4 * c * d)
encode_pair_cryptic gives exactly the same results as encode_pair. I'll give one example, and leave the reader to figure out the equivalence.
>>> encode_pair(47, -53)
-9995
>>> encode_pair_cryptic(47, -53)
-9995
I'm no math wiz but found this question kinda fun so I gave it a shot. This is by no means scalable to large number since I'm using prime numbers as exponents and gets out of control really quick. But tested up to 90,000 combinations and found no duplicates.
The code below has a couple extra functions generateValues() and hasDuplicates() that is just there to run and test multiple values coming from the output of myFunction()
BigNumber.config({ EXPONENTIAL_AT: 10 })
// This function is just to generate the array of prime numbers
function getPrimeArray(num) {
const array = [];
let isPrime;
let i = 2;
while (array.length < num + 1) {
for (let j = 2; (isPrime = i === j || i % j !== 0) && j <= i / 2; j++) {}
isPrime && array.push(i);
i++;
}
return array;
}
function myFunction(a, b) {
const primes = getPrimeArray(Math.max(a, b));
// Using the prime array, primes[a]^primes[b]
return BigNumber(primes[a]).pow(primes[b]).toString();
}
function generateValues(upTo) {
const results = [];
for (let i = 1; i < upTo + 1; i++) {
for (let j = 1; j < upTo + 1; j++) {
console.log(`${i},${j}`)
results.push(myFunction(i,j));
}
}
return results.sort();
}
function hasDuplicates(arr) {
return new Set(arr).size !== arr.length;
}
const values = generateValues(50)
console.log(`Checked ${values.length} values; duplicates: ${hasDuplicates(values)}`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/8.0.2/bignumber.min.js"></script>
Explanation of what's going on:
Using the example of myFunction(1,3)
And the array of primes [2, 3, 5, 7]
This would take the 2nd and 4th items, 3 and 7 which would result in 3^7=2187
Using 300 as the max generated 90,000 combinations with no duplicates (However it took quite some time.) I tried using a max of 500 but the fan on my laptop sounded like a jet engine taking off so gave up on it.
If x and y are some fixed size integers (eg 8 bits) then what you want is possible if the return of f has at least as many bits as the sum of the number of bits of x an y (ie 16 in the example) and not otherwise.
In the 8 bit example f(x,y) = (x<<8)+y would do. This is because if g(z) = ((z>>8), z&255) then g(f(x,y)) = (x,y). The impossibility comes from the pigeon hole principle: if we want (in the example) to map the pairs (x,y) (of which there 2^16) 1-1 to some integer type, then we must have at least 2^16 values of this type.
function myfunction(x,y){
x = 1/x;
y = 1/y;
let yLength = ("" + y).length
for(let i = 0; i < yLength; i++){
x*=10;
}
return (x + y)
}
console.log(myfunction(2,12))
console.log(myfunction(21,2))
Based on your question and you comments, I understood the following:
You want to pass 2 real numbers into a function. The function should use mathematical operators to generate a new result.
Your question is, if there is any kind of mathematical equation/function you could use, that would ALWAYS deliver a unique result.
If that's so, then the answer is no. You can make your function as complicated as possible and get a result(c) using the two numbers (a & b).
In this case I would look for another combination which could give me the result(c) using the same equation/function. Therefore I would use the system of linear equation to solve this mathematical issue.
In general, a system with fewer equations than unknowns has infinitely many solutions, but it may have no solution. Such a system is known as an underdetermined system.
In our case we would have one equation which gives us one result and two unknowns, therefore it would have infinitely many solutions because we already have a solution, so there is no way for the system to have no solutions at all.
More about this topic.
Edit:
I just recognized that some of us understood the domain of the function in a different way. I was thinking about real numbers (R) but it seems many assumed you talk about integers (Z) only.
Well I guess
real integers
wasnt clear enough, at least for me.
So if we would use integers only, I have no idea if that is possible to always have different results. Some users suggested a topic about that here I am also interested to take a look into that too.
How to calculate fibonacci function by math formula
I have try this formula but not work:
fib(n) = ((1 + 5^0.5) / 2)^n - ((1 - 5^0.5) / 2)^n / 5^0.5
const fib=(n)=>{
return ((1+(5**0.5))/2)**n-((1-(5**0.5))/2)**n/(5**0.5)
}
Any one know how to do?Thanks.
The formula is correct you just need to put some extra ().
const fib=(n)=>{
return (((1+(5**0.5))/2)**n-(((1-(5**0.5))/2)**n))/(5**0.5)
}
for(let i = 0;i<9;i++){
console.log(fib(i))
}
First thing I'd do is define φ
var φ = (1 + 5 ** 0.5) / 2;
Then a slightly shorter form is:
var fib = (n) => (φ ** n - ((-φ) ** -n)) / (2 * φ - 1);
Because you want an integer as a result, you could also throw in the call to Math.round().
You seem to be trying to recreate Binet's Formula. You can break down the formula a little like so, such that is becomes more readable:
const fib = n => {
const alpha = 5**0.5
const beta = alpha / 2;
return (1 / alpha) * ((0.5 + beta) ** n - (0.5 - beta) ** n);
}
console.log(fib(10));
Given a number, x (like 13), and a factor N (like 2), how can I compute the values 8 and 16 below?
8 <= 13 < 16
In other words, how can I compute the two ends of the equality here:
N^? <= x < N^(? + 1)
You could take the floored nth logarithm of the number and use it as value for getting the power of f and f plus one.
function getInterval(x, n) {
var f = Math.floor(Math.log(x) / Math.log(n));
return [Math.pow(n, f), Math.pow(n, f + 1)];
}
console.log(getInterval(3, 2).join(' '));
console.log(getInterval(23, 7).join(' '));
console.log(getInterval(13, 2).join(' '));
Edit. Question sense was completely changed.
pwr = Math.floor(Math.log(x) / Math.log(n))
low = Math.pow(n, pwr)
high = Math.pow(n, pwr + 1)
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?
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 are
bitMask = 1011, evenPower = 3, result = 3
bitMask = 101, evenPower = 3*3 = 9, result = 3*9 = 27
bitMask = 10, evenPower = 9*9 = 81, result = 27
bitMask = 1, evenPower = 81*81 = 6561, result = 27*6561 = 177147
That 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.
/**
* A fast routine for computing integer powers.
* Code adapted from {#link efficient power} by Patricia Shanahan pats#acm.org
* Almost identical to the method Knuth gives on page 462 of The Art of Computer Programming Volume 2 Seminumerical Algorithms.
* #param l number to be taken to a power.
* #param n power to take x to. 0 <= n <= Integer.MAX_VALUE
* Negative numbers will be treated as unsigned positives.
* #return x to the power n
*
*/
public static final double power(double l,int n)
{
assert n>=0;
double x=l;
switch(n){
case 0: x = 1.0; break;
case 1: break;
case 2: x *= x; break;
case 3: x *= x*x; break;
case 4: x *= x; x *= x; break;
case 5: { double y = x*x; x *= y*y; } break;
case 6: { double y = x*x; x = y*y*y; } break;
case 7: { double y = x*x; x *= y*y*y; } break;
case 8: x *= x; x *= x; x *= x; break;
default:
{
int bitMask = n;
double evenPower = x;
double result;
if ( (bitMask & 1) != 0 )
result = x;
else
result = 1;
bitMask >>>= 1;
while ( bitMask != 0 ) {
evenPower *= evenPower;
if ( (bitMask & 1) != 0 )
result *= evenPower;
bitMask >>>= 1;
} // end while
x = result;
}
}
return x;
}
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
exp(x) = 1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120 + x^6/6! + ...
ln(1+x) = x - x^2 /2 + x^3 /3 - x^4 / 4 + x^5 / 5 - x^6/6 + ... |x|<1
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) and ln(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)
int b = Float.floatToIntBits(x);
int sign = (b & 0x80000000) == 0 ? 1 : -1;
int mattissa = b & 0x007fffff;
int ex = ((b & 0x7f800000) >> 23 ) - 127;
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)
int bits = mattissa | 0x3f800000;
float z = Float.intBitsToFloat(bits);
if(z>root2) {
z = z/2;
++ex;
}
Use this function to find the log of 1+x using a taylor series
static float ln1px(float x) {
float x_2 = x*x; // powers of x
float x_3 = x_2 * x;
float x_4 = x_3 * x;
float x_5 = x_4 * x;
float x_6 = x_5 * x;
float res = x - x_2 /2 + x_3 /3 - x_4 / 4 + x_5 / 5 - x_6/6;
return res;
}
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
float w = z - 1;
float ln_z = ln1px(w);
float ln_x = ln_z + ln2 * ex;
System.out.println("ln "+ln_x+"\t"+Math.log(x));
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 the x^n. Writing x=m*2^ex then ln((m*2^ex)^a) = yln(m) + yex*ln(2) and
x^a=exp(ln((m*2^ex)^a)) = exp(a * ln(m)) * exp(a * ln(2))^ex
the 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
static float exp(float x) {
float x_2 = x*x; // powers of x
float x_3 = x_2 * x;
float x_4 = x_3 * x;
float x_5 = x_4 * x;
float x_6 = x_5 * x;
float res = 1+ x + x_2 /2 + x_3 /6 + x_4 / 24 + x_5 / 120 + x_6/ 720;
return res;
}
finally we can put the pieces together
// Get integer and fractional parts of y
int n = (int) Math.floor(y);
float a = y-n;
float x_n = power(x,n); // x^n
float a_ln_m = a * ln_z; // ln(m^a) = a ln(m)
float a_ln_2 = a * ln2; // ln(2^a) = a ln(2)
float m_a = exp(a_ln_m); // m^a = exp(a ln(m))
float _2_a = exp(a_ln_2); // 2^a = exp(a ln(2))
float _2_a_ex = power(_2_a,ex); // (2^ex)^a = 2^(a*ex) = (2^a)^ex
float x_a = m_a * _2_a_ex; // x^a = m^a * 2^(a*ex)
float x_y = x_n * x_a; // x^y = x^n * x^a
System.out.println("x^y "+x_y+"\t"+Math.pow(x,y));
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?
Those are some really nice examples, here is a simpler one too.
function exponential(a,b){
var c = 1;
for(var i=1; i<=b; i++){
c = c * a;
}
return c;
}
now call the function:
exponential(2,4);
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)
function power(x,n) {
if(n === 0) return 1;
if(n === -1) return 1/x;
if(n === 1) return x;
return Math.exp(n*Math.log(x))
}
console.log(power(2,3.5));
I added some basic checks (n===0)... To fasten things up in case.
Flexo sums it up:
The general algorithm tends to be computing the float power as the
combination of the integer power and the remaining root. The integer
power is fairly straightforward, the root can be computed using either
Newton - Raphson method or Taylor series. IIRC numerical recipes in C
has some text on this. There are other (potentially better) methods
for doing this too, but this would make a reasonable starting point
for what is a surprisingly complex problem to implement. Note also
that some implementations use lookup tables and a number of tricks to
reduce the computation required.
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