ArbitraryPrecision.frink


// Functions for performing calculations to arbitrary precision.

// See http://en.literateprograms.org/Arbitrary-precision_elementary_mathematical_functions_(Python)

arbitraryExp[x, digits=getPrecision[]] :=
{
   origPrec = getPrecision[]
   setPrecision[digits+3]

   if x < 0
      s = 1.0 / arbitraryExp[abs[x],digits]
   else
   {
      xpower = 1.
      ns = 0.
      s = 1
      n = 0.
      factorial = 1.
      while s != ns
      {
         s = ns
         term = xpower / factorial
         ns = s + term
         xpower = xpower * x
         n = n + 1.
         factorial = factorial * n
//         println["s is $s"]
      }
   }
   setPrecision[digits]
   retval = 1.0 s

   setPrecision[origPrec]
   return retval
}


// Natural log to arbitrary precision.
arbitraryLn[x, digits=getPrecision[]] :=
{
   if x <= 0
      return "Error:  Arbitrary logs of negative numbers not yet implemented."
   
   origPrec = getPrecision[]
   setPrecision[digits+3]

   eps = 10.^-(digits+1)

   // A good initial estimate is needed
   if (x < 10^308)
      r2 = ln[x]
   else                         // TODO:  Store ln[2] somewhere.
      r2 = approxLog2[x] * ln[2]

//   println["Epsilon is $eps"]

   // Use Newton's method
   do
   {
      r = r2
//      println["r is $r"]
      r2 = r + x/arbitraryExp[r,digits+2] - 1.
   } while abs[r2-r] > eps
   setPrecision[digits]
   retval = 1. r
   
   setPrecision[origPrec]
   return retval
}

// Arbitrary log to the base 10.
arbitraryLog[x, digits=getPrecision[]] :=
{
   origPrec = getPrecision[]
   setPrecision[digits+2]
// TODO:  Store ln[10] somewhere.
   retval = arbitraryLn[x, digits+2] / arbitraryLn[10, digits+2]
   setPrecision[origPrec]
   return 1. retval
}


View or download ArbitraryPrecision.frink in plain text format


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 14705 days, 19 hours, 50 minutes ago.