A while ago I wrote a post on estimating Pi using a variety of methods. As a sort of follow-up I will now write a post on estimating *e*, or Euler's Number, in Python.

I won't try to summarize what *e* is or what it is used for as Wikipedia has a comprehensive article on the subject. However, I will include a portrait of Leonhard Euler just after he had washed his hair and changed into his pyjamas.

*Swiss mathematician Leonhard Euler15 April 1707 to 18 September 1783*

Let's dive straight into the code which lives in a single file called e.py. (At least you can't accuse me of using overly long filenames). You can download the source code as a zip or clone/download the Github repository.

Source Code Links

This is the first part of the source code.

e.py (part 1)

import math

E15DP = "2.718281828459045"

RED = "\x1B[31;1m"

GREEN = "\x1B[32;1m"

WHITE = "\x1B[37;1m"

RESET = "\x1B[0m"

def main():

print("-----------------")

print("| codedrome.com |")

print("| Estimatinge |")

print("-----------------\n")

expansion_1()

#expansion_2()

#newtons_series()

#brothers_formula()

def print_as_text(e):

"""

Takes a value for e and prints it below a definitive value,

with matching digits in green and non-matching digits in red

"""

e_string = "{:1.15f}".format(e)

print("Definitive: " + WHITE + E15DP + RESET)

print("Estimated: ", end="")

for i in range(0, len(e_string)):

if e_string[i] == E15DP[i]:

print(GREEN + e_string[i] + RESET, end="")

else:

print(RED + e_string[i] + RESET, end="")

print("\n")

Near the top of the file I have defined a variable called E15DP which is a string containing *e* to 15 decimal places. This will be used as a definitive value to compare with values we calculate. The name is all upper case to denote that it should be considered as a constant.

Next we have a few colour constants to output text to the console in various colours.

The main function consists of four function calls to estimate *e* using various methods. All but the first are commented out for now as we'll run them one at a time.

The print_as_text function takes a value for *e* and converts it to a string with 15 decimal places. It then prints it after the definitive value, with correct digits in green and incorrect ones in red.

e.py (part 2)

def expansion_1():

print(WHITE + "First expansion\nn = 100000\n---------------" + RESET)

n = 100000

e = (1 + 1/n)**n

print_as_text(e)

The first function to calculate *e* is expansion_1 which implements this formula...

First Expansion

e = (1 + 1/n)^{n}

...with a value of n = 100000

We now have enough to run with this command.

Running the program

python3.7 e.py

The output is

Program Output

-----------------

| codedrome.com |

| Estimating e |

-----------------

**First expansion
n = 100000
---------------**

Definitive:

**2.718281828459045**

Estimated:

**2.718268237192297**

As you can see this gives us 4dp of accuracy; you might like to experiment with different values of n. Now let's try another expansion to implement this formula with n = 0.000000001.

Second Expansion

e = (1 + n)^{1/n}

e.py (part 3)

def expansion_2():

print(WHITE +

"Second expansion\nn = 0.000000001\n----------------" +

RESET)

n = 0.000000001

e = (1 + n)**(1/n)

print_as_text(e)

Comment out expansion_1() in main, uncomment expansion_2() and run the program again. This is the output.

Program Output

-----------------

| codedrome.com |

| Estimating e |

-----------------

**Second expansion
n = 0.000000001
----------------**

Definitive:

**2.718281828459045**

Estimated:

**2.718282052011560**

This gives us 5dp of accuracy but again you can try different values of n.

Now let's move on to the third method, Newton's Series, for which the formula is:

This means we start off with n = 0, set *e* to 1/n!, increment n and then keep adding 1/n! to *e* for as long as we want.

(*n! means the product of all integers up to and including n, for example 4! = 4 x 3 x 2 x 1 = 24. Incidentally 0! = 1*.)

e.py (part 4)

def newtons_series():

print(WHITE + "Newton's Series\nn = 0 to 12\n---------------" + RESET)

e = 0

for n in range(0, 13):

e += (1 / math.factorial(n))

print_as_text(e)

Uncomment newtons_series() in main and run the program.

Program Output

-----------------

| codedrome.com |

| Estimating e |

-----------------

**Newton's Series
n = 0 to 12
---------------**

Definitive:

**2.718281828459045**

Estimated:

**2.718281828286169**

Sir Isaac gives us 9dp of accurancy with a maximum value of n = 13.

As with π people are still working on ways to calculate *e* and I'll finish off with this impressive recently discovered method, Brothers Formula, devised as recently as 2004.

As with Newton's Series this is the sum of a infinite series although rather more complex.

e.py (part 5)

def brothers_formula():

print(WHITE + "Brothers Formula\nn = 0 to 8\n----------------" + RESET)

e = 0

for n in range(0, 9):

e += (2*n + 2) / (math.factorial(2*n + 1))

print_as_text(e)

The extra complexity pays off though: we only need to count to 8 to get 15dp (possibly more) of accuracy.

Program Output

-----------------

| codedrome.com |

| Estimating e |

-----------------

**Brothers Formula
n = 0 to 8
----------------**

Definitive:

**2.718281828459045**

Estimated:

**2.718281828459045**