until we get native math functions in the amxx core, here is a little something I did on AMX forums a while back. it's so cool I have to repost.
"
This is really cool - took hours of research.
I've seen a few threads where people have needed what this will do (as I needed it in a plugin I'm working on).
This is a function, totally in raw AMX (no C++), that will calculate:
x^y, even when x and y are fractions/floating points!
It is as accurate as you want it to be.
Enjoy!
Below you can see the code that does it. After the code is a detailed math explanation (note - requires knowledge of calculus 3)
fpow(x,y) -- finds x^y with floating points
ipow(x,y) -- finds x^y, with only x as a float
factorial(n) -- finds n!
ln(x) -- finds natural logarithm of n, or ln(x)
Code:
Float:fpow(Float:x, Float:y)
{
new Float:sum = 0.0
new i
for (i=0; i<=EXP_N; i++) {
sum += ipow((y*ln(x)), float(i)) / float(factorial(i))
}
return sum
}
Float:ln(Float:x)
{
new Float:sum = 0.0
new i
for (i=1; i<=LN_N; i++) {
sum += ipow((x-1)/x, float(i)) / float(i)
}
return sum
}
Float:ipow(Float:x, Float:y)
{
new i, Float:sum=1.0
if (y == 0.0) {
return float(1)
}
for (i=1; i<=floatround(y); i++) {
sum = sum * x
}
return sum
}
factorial(n)
{
new i
if (n<1) {
return 1
}
for (i=n-1; i>=1; i--) {
n = n*i
}
return n
}
This is very cool because of the simplistic beauty behind it.
This is algebraic manipulation, Taylor series, and trivial calculus.
First, you need an understanding of basic Calculus 3.
From
x^y we can take the exponential of the natural log:
x^y=
e^(ln(x^y))
e^(ln(x^y))=
e^(y*ln(x))
Then take the taylor series of e^x:
SUM(x^n/n!,0,infinity), or:
x^0/0! + x^1/1! + x^2/2! + x^3/3! + x^4/4! ... or:
1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120 ...
Then subsitute for x, y*ln(x):
1 + (y*ln(x))/1 + (y*ln(x))^2/2 + (y*ln(x))^3/6 + (y*ln(x))^4/24 + (y*ln(x))^5/120 ...
To quickly find a basic approximation for ln(x), we can use a quick ln(x) expansion:
SUM((((x-1)/(x))^n)/n, 1, infinity), or:
(x-1)/x + .5*((x-1)/x)^2 + (1/3)*((x-1)/x)^3 ...
We can finally write that x^y is something like:
SUM(SUM((((x-1)/(x))^n)/n, 1, infinity)^n/n!,0,infinity), or:
Code:
i n ^i
------- / --- ((x-1)/x)^n \
\ | \ ----------- |
\ y| / n |
\ | --- |
/ \ 1 /
/ ----------------------
/ i!
-------
0
This formula will converge to x^y. Enjoy!
__________________