floatingPointBase.frink

View or download floatingPointBase.frink in plain text format


/** This function converts a floating-point number into a string
    representation in the specified base with the specified number of
    characters of precision.

    Note that if the precision of the original number is less than the
    requested digits, some of the digits in the requested base will be illusory

    TODO:  Add units of measure?
*/

base[n, base, digits] :=
{
   if isInteger[n]
      return base[n, base]

   signum = realSignum[n]
   str = (signum < 0 ? "-" : "")

   n = abs[n]
   intPart = trunc[n]

   // Convert the integer part to the specified base
   intStr = base[intPart, base]
   str = str + intStr + "."
   digits = digits - length[intStr] // Calculate how many more digits needed
   n = n - intPart   // n now contains the fractional part

   // 1.  shift the radix point to the left in the base you're working
   // in (e.g.  if you're working in base 3, and want at least 20 digits in
   // your result, you multiply your numerator by 3^20)
   shift = base^digits

   prec = getPrecision[]
   try
   {
      // Calculate how many digits we need to calculate in the specified base.
      setPrecision[ceil[digits * ln[digits] / ln[10] + 1]]

      // 2. Do the shift left and take the integer part.
      shifted = trunc[n * shift]

      // 3. Convert the resulting integer to the base using integer functions.
      resStr = base[shifted, base]

      // 4. Pad the fractional part with the necessary number of zeroes.
      str = str + padLeft[resStr, digits, "0"]
   }
   finally
   {
      setPrecision[prec]
   }

   return str
}


/** Parse a string containing a floating-point number in the specified base.

    THINK ABOUT:
    Since a floating-point number specified in one base quite likely cannot be
    exactly represented in another base with a finite number of digits, have a
    parameter to set requested significant digits in result?
*/

parseFloat[str, base] :=
{
   //   str =~ %s/_//g    // Remove optional underscores
   if [sign, intPart, fracPart] = str =~ %r/([\-\+]?)(\w*)\.?(\w*)/
   {
      n = 0.
      if intPart != ""
         n = n + parseInt[intPart, base]

      if fracPart != ""
         n = n + parseInt[fracPart, base] / (base^ length[fracPart])

      if sign == "-"
         return -n
      else
         return n
      
   } else
   {
      println["parseFloat: unmatched string $str"]
      return undef
   }
}


View or download floatingPointBase.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 17592 days, 15 hours, 41 minutes ago.