Recently I've been working on writing my own Math library in C#. It's not meant to be a serious improvement on anything that already exists, but is more of a learning experience for me. I'm sure that every programmer after using library functions for a while begins to wonder "hey, how does that function work!?" Well, I did, and this is part of the result.
So far I've implemented most of the functions, but the other day I got to
The Logarithm weren't that bad. I had come up with a recursive algorithm about 2 years ago that would solve the Logarithm for any base. It wasn't the fastest function in the world, but it was simple, and easy to use, and I'm proud I came up with it myself. Here it is for anyone who's interested.
public static double Log(double Power, double Base)
double Whole, N, Sign;
Sign = 1.0;
#region Error Checking
if (Power <= 1.0 || Base <= 1.0)
if (Power <= 0.0 || Base <= 0.0 )
if (Power < 1.0)
Power = 1.0 / Power;
Sign *= -1.0;
if (Base < 1.0)
Sign *= -1.0;
Base = 1.0 / Base;
if (Power == 1.0)
if (Base != 1.0)
Whole = Power;
N = 0.0;
while (Whole >= Base)
Whole /= Base;
if (Whole == 1.0)
return (Sign * N);
return Sign * (N + (1.0 / Log(Base, Whole)));
Like I said, it's pretty easy to use. It can be used to solve for any base, whether it be E, 2, 10, etc. But as I said, it's not the fastest, and it is a little memory intensive compared to other functions. I had read that there was a Taylor series that could be used to find the Natural Logarithm of a number, but when I implemented it, it was painfully slow, and in many cases just flat out didn't work.
During my research though I had discovered that there was a Taylor Series for finding the Power of E (e^x)
public static double Exp(double Exponent)
double X, P, Frac, I, L;
X = Exponent;
Frac = X;
P = (1.0 + X);
I = 1.0;
Frac *= (X / I);
L = P;
P += Frac;
}while(L != P);
Sweet, simple, and to the point. That's how a function should be.
But after several hours of looking, I could not find hide nor hair of an algorithm for the Natural Logarithm...
Then it hit me.
(stupid function; won't watch where it's going)
Several years ago I read about an algorithm by a mathematician named John Gabriel, which he came up with to find the Nth Root of a number. (Unfortunately his website seems to be gone, but they have a copy of his algorithm here
public static double NthRoot(double Power, double Rt)
double A, N, S, T, L, R;
A = Power;
N = Rt;
S = 1.0;
T = S;
L = (A / Math.Pow(S, (N - 1.0)));
R = (N - 1.0) * S;
S = (L + R) / N;
}while(L != S);
For one thing, I hadn't come up with a Pow function yet, so I did't want to implement this in my library yet.
we already knew the Root, which is E, and we had a sweet and simple function that could raise E to any power, (which I just might happen to have lying around) if I then solved for N instead, would it give me the Natural Logarithm of the number?
You guessed it.
public static double Ln(double Power)
double N, P, L, R, A, E;
E = 2.71828182845905;
P = Power;
N = 0.0;
while(P >= E)
P /= E;
N += (P / E);
P = Power;
A = N;
L = (P / (Exp(N - 1.0)));
R = ((N - 1.0) * E);
N = ((L + R) / E);
}while(N != A);
If you wanted to use it to solve the logarithm of any other number you would do this.
public static double Log(double N, double B)
return (Ln(N) / Ln(B));
And what's even nicer is that once you have a function for the Logarithm as well as the Exponentiation of E, you could use them together for several other functions.
If for instance we wanted to find the AntiLog (Find B in [B ^ E = P]) we would use this.
public static double ALog(double Power, double Exponent)
double T = Ln(Power);
T /= Exponent;
And even more useful, if we wanted to make a Pow function, we do this.
public static double Pow(double Base, double Power)
return Exp(Power * Ln(Base));
Ahhh, the joy and pain that comes with Logarithms and Exponents.
Well I hope you've all enjoyed this little journey with me. I'm very proud that I was able to get these functions working. These are some of the most basic algorithms that we use everyday, and I hope you all get a kick out of seeing what goes on backstage.
Before I end this I would like to say two things.
1) Please don't use these and expect to get the same sort of speed and efficiency you would in the System.Math Library. Those functions have been crafted for speed and precision, so don't expect these to match them. As I said at the start, they're not meant to be an improvement, just a learning tool.
2) Please be careful when using these, I haven't added any Error Checking, so it is possible this will throw an ArithmeticException(). Please also be especially careful when comparing floating point numbers. I edited them slightly from what I actually have in order to make them easier on the eyes. One way to do this would be to put a Counter variable in the Loops to make them stop at a certain number, somewhere between 25 and 30 should do.
Again, I hope you've all enjoyed this and learned something from it.