Euler's Number

Calculating ℯ to high precision in a web browser

Written by Guy Fernando

Created Jan 2023 - Last modified Nov 2024


Euler's ℯ Symbol



The number ℯ, also known as Euler's Number refers to a mathematical expression for the base of the natural logarithm, and is an important constant number in mathematics. It is a transcendental number, meaning that it is not the root of a non-zero polynomial with finite degree with rational coefficients. The value of ℯ quoted to ten decimal places is approximately 2.7182818284.

The Magic of ℯ

An exponential function can be mathematically expressed in the form y = ax, where ‘x’ is the independent variable, ‘y’ the dependent variable, and ‘a’ is a constant known as the base of the function. The value of ‘a’ determines the exponential growth, the larger the value of ‘a’ the higher the rate of exponential growth. Many examples of this kind of growth are experienced in nature, physics, and economics.

There is a single special case for ‘a’, when the derivative or slope of the growth curve is the same as its value, similarly the integral or area under the growth curve is also the same as its value. The special case is when ‘a’ is equal to the constant ℯ.

    \( \begin{aligned} \frac{d}{dx} e^{x} = e^{x} \end{aligned} \)

\( \begin{aligned} \int e^{x} dx = e^{x} + C \end{aligned} \)    

Knowing this property greatly simplifies the work involved when solving calculus.

Try changing the value of the 'a' coefficient towards the value of ℯ to see all the curves below converge. Notice that derivative(ax) and integral(ax) are only equal to ax when a = 2.72 (i.e. when ≈ ℯ).


Brief History of ℯ

In 1683 Jacob Bernoulli discovered the ℯ constant while studying compound interest when payments of interest ‘n’ occur more frequently. The expression below approaches ℯ as the limit approaches infinity:

\( \begin{aligned} e = \lim_{n \rightarrow \infty } \big(1 + \frac{1}{k} \big)^{k} \end{aligned} \)

Leonhard Euler extended and formalized the work of Bernoulli as well as other areas in mathematics. In 1748 he published ideas of ℯ in his two volume book entitled Introductio in analysin infinitorum, where he described the logarithm to base ℯ as the natural or hyperbolic logarithm, and gave this infinite series:

\( \begin{aligned} e^{x} = \sum_{k=0}^\infty \frac{ x^{k} }{k!} = \frac{1}{0!} +\frac{x}{1!} + \frac{ x^{2} }{2!} + \frac{ x^{3} }{3!} + ... \end{aligned} \)

By setting x = 1 we get an expression for evaluating ℯ:

\( \begin{aligned} e = \sum_{k=0}^\infty \frac{1}{k!} = \frac{1}{0!} +\frac{1}{1!} + \frac{1}{2!} + \frac{1}{3!} + ... \end{aligned} \)

The online ℯ calculator described next uses this infinite series as an algorithm for calculating ℯ to a high precision.

Online ℯ Calculator

The online ℯ calculator presented here is able to evaluate ℯ up to one million decimal places the previously described infinite series algorithm. Bear in mind the more digits selected, the longer the calculation will take to complete. Be prepared to wait around sometime when calculating ℯ to more than 1000 digits, though this will depend on the speed of your computer, and the algorithm chosen. When the calculation completes, the result will be displayed below.

Select the number of digits to calculate, and then click the Calculate button.




 


The process of evaluating ℯ when using an infinite series involves a repetition of calculations, the more repetitions we use the better the approximation. Whether performing these calculations by hand or using a digital computer, it is obviously advantageous to arrive upon an answer with the fewest of repetitions. Some infinite series equations converge faster than others, which is another way of saying that the value is arrived upon more quickly for a given amount of repetitions or iterations.

Infinite Series Algorithm

The Euler number ℯ can be represented as an infinite series.

\( \begin{aligned} e = \sum_{k=0}^ \infty \frac{{1}}{k!} \end{aligned} \)

\( \begin{aligned} \hspace{3mm} = 1 + \frac{1}{1} + \frac{1}{1.2} + \frac{1}{1.2.3} + \cdots \end{aligned} \)

Digits calculated per iteration: 2
Computational complexity: \( \begin{aligned} O( k^2 ) \end{aligned} \)

The JavaScript implementation is shown here.

        
  // Calculating e using the Infinite series.
  // Guy Fernando (2023)

  Decimal.precision = this.digits + 2;

  var euler = new Decimal(0);
  var iterations = (this.digits / this.digitsPerIteration);

  // Infinite series.
  for (var k = 0; k < iterations; k++) {
      // Partial summation.
      euler = euler.plus(Decimal(1).dividedBy(this.factorial(k)));
  }

  // Set significant digits.
  euler = euler.toSD(this.digits);
        
      

Big 'O' Notation

In computer science, the Big 'O' notation is used as a basis to quantify computational complexity. The notation applies to algorithms that are repetitive such as in a software loop construct, k being the number iterations before the loop terminates. The notation is a technique used to classify an algorithm's running time for a given number of iterations. Since the algorithms presented here all share the same structure, they too share the same computational complexity classification.

Computation Method Used Here

The computation is performed within your web browser using JavaScript. The calculation is executed in a separate web worker thread to allow this web page to remain responsive and to be scrolled while the calculation is in progress.

To evaluate an approximation of ℯ to high precision, the built-in 64-bit IEEE 754 floating point numerical system that JavaScript uses cannot be used beyond 15 decimal places. To achieve higher accuracy, an arbitrary precision numeric library such as Decimal.js is used. Decimal.js is a self contained open-source library with a large community of users. It is used to calculate all the algorithms presented in this article to a precision of up to a million decimal places.

The full javascript code listing is shown here.

        
          
          
// Guy Fernando (2023).
// Calculates e using various algorithms.
// Implementation using arbitary precision arithmetic library, decimal.js.

importScripts('decimal.min.js');

// Abstract base class for calculating e.
//
class EulerAlgorithm {
    // Constructor.
    //
    constructor(digits, digitsPerIteration) {
        this.digits = digits;
        this.digitsPerIteration = digitsPerIteration;
        this.startTime = 0;
        this.endTime = 0;
    }

    // Factorial that doesn't overflow with large n.
    //
    factorial(n) {
        try {
            var i = 2, r = new Decimal(1);
            for (; i <= n; r = r.times(i++))
                ;
        }
        catch (err) {
            console.log(err.message);
        }

        return r;
    }

    // Gets the time taken in milliseconds to calculate a single e digit.
    //
    getTimePerDigit() {
        return ((this.endTime - this.startTime) / this.digits).toFixed(2);
    }
}

// Infinite Series method for calculating e.
//
class Infinite extends EulerAlgorithm {
    // Constructor.
    //
    constructor(digits) {
        // The number of digits, and decimal digits the algorithm generates per iteration.
        super(digits, 2);
    }

    // The Infinite series e calculation.
    //
    calculate() {
        try {
            // Journal start time.
            this.startTime = performance.now();

            Decimal.precision = this.digits + 2;

            var euler = new Decimal(0);
            var iterations = (this.digits / this.digitsPerIteration);

            // Infinite series.
            for (var k = 0; k < iterations; k++) {
                // Partial summation.
                euler = euler.plus(Decimal(1).dividedBy(this.factorial(k)));
            }

            // Set significant digits.
            euler = euler.toSD(this.digits);

            // Journal end time.
            this.endTime = performance.now();

            return euler;
        }
        catch (err) {
            console.log(err.message);
            return 0;
        }
    }
}

// Web worker message receiver.
//
self.onmessage = function (event) {
    // Reconstitute json object containing parameters.
    var jsonParameters = JSON.parse(event.data);

    // Extract parameters.
    var digits = Number(jsonParameters.Digits);
    var algorithm = jsonParameters.Algorithm;

    // Instantiate required algorithm.
    // So far the Infinite Series is the only algorithm implemented.
    var e;
    switch (algorithm) {
        case "Infinite Series":
            e = new Infinite(digits);
            break;
    }

    // Perform pi calculation.
    const eValue = e.calculate();
    const timePerDigit = e.getTimePerDigit();

    // Send json message containing results to main thread.
    var jsonResult = { Algorithm: algorithm, Digits: digits, EValue: eValue.toString(), TimePerDigit: timePerDigit.toString() };
    self.postMessage(JSON.stringify(jsonResult));
};

        
      

Conclusion

The algorithm presented in this article is an infinite series, as a result computational memory requirements and execution time will be a function of the number of digits that need to be calculated. Furthermore the computer memory requirements will roughly be proportional to the number of digits required, and the computer execution time per digit will exponentially increase as the number of digits required increases.

Decimal.js is an excellent small footprint arbitrary-precision library for JavaScript. It lends itself perfectly for evaluating infinite series algorithms as described in this article.