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));
};