# e.frink

```/**  Program to calculate e to arbitrary precision.  This uses binary      splitting for speed.      You usually use this by calling E.getE[digits] which will return e      to the number of digits you specify.      This version has been updated to be fastest with      Frink: The Next Generation.  Due to limitations in Java's BigDecimal      class, this is limited to a little over 101 million digits.      This differs from the basic algorithm in eBinarySplitting.frink      because when you ask for more digits of e than you previously had,      this *resumes* the calculation rather than starting from scratch.      See:      http://numbers.computation.free.fr/Constants/Algorithms/splitting.html      http://www.ginac.de/CLN/binsplit.pdf */ class E {    class var largestDigits = -1    class var cacheE = undef    /** These variables help us resume the state of the binary-splitting        algorithm. */    class var largestP = 1    class var largestQ = 1    class var largestK = 1    class var logFactorial = 0.    /** This is the main public method to get the value of e to a certain        number of digits, calculating it if need be.  If e has already been        calculated to a sufficient number of digits, this returns it from the        cache.    */    class getE[digits = getPrecision[]] :=    {       origPrec = getPrecision[]       try       {          setPrecision[digits]          if (largestDigits >= digits)             return 1. * cacheE          else             return 1. * calcE[digits]       }       finally          setPrecision[origPrec]    }    /** This is an internal method that calculates the digits of e if        necessary. */    class calcE[digits] :=    {       origPrec = getPrecision[]       try       {          setPrecision          // Find number of terms to calculate.          // ln[x!] = ln + ln + ... + ln[x]          logMax = digits * ln          k = largestK                    while (logFactorial < logMax)          {             logFactorial = logFactorial + ln[k]             k = k + 1          }          setPrecision[digits+3]          if largestK < k    // We may have already calculated enough!          {             if (largestK == 1)  // This is the first iteration             {                p = P[0,k]                q = Q[0,k]             } else             {                // Continuing iterations                pmb = P[largestK, k]                qmb = Q[largestK, k]                p = largestP qmb + pmb                q = largestQ qmb             }             // Store the biggest values back in the cache             largestP = p             largestQ = q             largestK = k                          cacheE = 1 + (1. * p)/q          }                    setPrecision[digits]          return 1. * cacheE       }       finally          setPrecision[origPrec]    }    /** Private method for binary splitting. */    class P[a,b] :=    {       if (b-a) == 1          return 1              m = (a+b) div 2       r = P[a,m] Q[m,b] + P[m,b]       return r    }    /** Private method for binary splitting. */    class Q[a,b] :=    {       if (b-a) == 1          return b              m = (a+b) div 2       return Q[a,m] Q[m,b]    } }```

This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 19097 days, 3 hours, 52 minutes ago.