# User:Creature/Logarithms

After spending some time studying mathematics, I've found of a fairly easy way to calculate logarithms in your operating system. Note that there are a few downsides to this way as well, which will be described in a moment.

## Contents |

## Logarithms

### Requirements

Firstly, there are a few requirements you need to meet in order to be able to use this method. You will need:

- Floating point support (see FPU for more details).
- Some implementation of the
**powf**function (a function that can raise float x to float y). If y is the power to raise to, then you must be able to handle the case where 0 < y < 1.

This is basically all you need.

### Downsides

The main downside of this method is precision: it is not very precise and the way I'm showing it to you may be improved (it is merely used for demonstration). The method will probably suffer from rounding errors.

### The Method

For the calculation of logarithms, we're going to use a couple of other facts.

Firstly, the derivative of an exponential function f(x) = a^x (where ^ denotes **to the power of**) is f'(x) = c * a^x. **c** is a constant number that depends on the growth factor (the growth factor is **a**). The number **c** can be calculated by

Δx lim a - 1 Δx->0 --------- Δx

But the derivative of function f(x) = a^x also equals g'(x) = ln(a) * a^x, where ln is the logarithmus naturalis of **a**. What we have now are two derivatives of one same function, which means we can compare them.

-> c * a^x = ln(a) * a^x f'(x) = g(x) -> c = ln(a) Dropa^x(exists in both terms) -> c = log(a) = the_limit_above ln(a) = log(a)

Note that **log** is the logarithmus naturalis in the standard C library (so the base number is Euler's mathematical constant, not 10).

From the definition of logarithms, we know that

a log10(x) log x = ---------- log10(a)

So when calculating the **ln** (or **log** in the standard C library) of x, **a** becomes **e**. Because log10(e) will never change, we can calculate this number and put it in a define somewhere. By my (quick and dirty) calculations, log10(e) equals approximately **0.4342944819**. Now we can transform our formula:

a 0.4342944819 * log x = log10(x)

Now, if we want to implement our C function **log** (which uses e as base, so a = e), we use the fact that log(x) = c and the limit.

float log10(float x) { return (((powf(x, 0.00001f) - 1) / 0.00001f) * LOG10_E); }

Where **LOG10_E** is the number calculated earlier. We raise **x** to the power of **0.00001f** because **Δx** approaches 0, so this is a fairly good choice (though inaccurate). Once you have log10, it's not hard to calculate the other logarithm functions:

float log(float x) { return (log10(x) / LOG10_E); }

We could even create a general function that calculates any type of logarithm:

// ----- Custom function that calculates the logarithm of value x with the given base. loat logx(float x, float base) { // base may not equal 1 or be negative. if(base == 1.f || base < 0.f) return 0.f; // Return what you want here, could be Not-A-Number or NAN. return (log10(x) / log10(base)); }

As I said, this method is inaccurate and probably could be improved to be more precise.

## Alternative implementation (courtesy of Combuster)

There is an alternative way (but more complex in theory) that can be used to calculate the **ln** of a value **x**. It is much more precise (since it uses a Taylor series expansion). Wikipedia has a very nice article on this, which can be found here. Once you have implemented this way, it is again not very hard to calculate other logarithmic values.