# floatingPointBase.frink

``` /** This function converts a floating-point number into a string     representation in the specified base with the specified number of     characters of precision. TODO:  Add units of measure?     args: [n, base, digits]       n: The number to convert       base:  The base to convert to, specified as an integer from 2 to 36.       digits:  The number of digits (in the specified base) that          will be produced in the string result.            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:  Make the number of digits try to echo the number of significant          digits in n?     returns:        A string representing the number n in the specified base. */ 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 + "."        // Calculate how many more digits needed    digits = max[0, digits - length[intStr]]    // 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.       newPrecision = ceil[digits * (ln[base]/ln) + 4]       // println["newPrecision is \$newPrecision"]       setPrecision[newPrecision]       n = n - intPart   // n now contains the fractional part       // 2. Do the shift left and take the integer part.       shifted = round[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?  It is currently     limited by the division and the current value of setPrecision[]     args:     [str, base, digits]:       str:  A string containing the number to parse.  This may contain a             positive or negative sign, an (optional) decimal point, and             optional underscores to separate digits.       base:  An integer from 2 to 36 indicating the base that the string is             represented in.       digits:  An optional argument that indicates the number of digits to             return in the result.             If digits is undef (the default), this will return an exact             rational number indicating the exact value represented by the             string.  This is the most precise interpretation.                          If digits is 0, this will attempt to return a number with the             approximate number of significant digits that are contained in the             number (plus up to 2 decimal digits.)  All digits will not be exact             in this case. */ parseFloat[str, base, digits=undef] := {    str =~ %s/_//g    // Remove optional underscores    if [sign, intPart, fracPart] = str =~ %r/([\-\+]?)(\w*)\.?(\w*)/    {       n = 0.       if digits == 0          digits = ceil[(length[intPart] + length[fracPart]) * ln[base]/ln+2]              if digits == undef       {          n = 0          // Return an exact rational number.          // 0 digits of precision would actually work in this case because          // we'll only have integers and rational numbers.          digits = getPrecision[]       }              if intPart != ""          n = n + parseInt[intPart, base]       origPrec = getPrecision[]       try       {          setPrecision[digits]          if fracPart != ""             n = n + parseInt[fracPart, base] / (base^ length[fracPart])          if sign == "-"             return -n          else             return n        }        finally        {           setPrecision[origPrec]        }           } else    {       println["parseFloat: unmatched string \$str"]       return undef    } } ```

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 18864 days, 23 hours, 17 minutes ago.