IEEE754.frink

View or download IEEE754.frink in plain text format


/** This file contains library utilities for processing IEEE-754 numbers.

Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents
the sign of the floating-point number. Bits 62-52 (the bits that are selected
by the mask 0x7ff0000000000000L) represent the exponent. Bits 51-0 (the bits
that are selected by the mask 0x000fffffffffffffL) represent the significand
(sometimes called the mantissa) of the floating-point number.

If the argument is positive infinity, the result is 0x7ff0000000000000L.

If the argument is negative infinity, the result is 0xfff0000000000000L.

If the argument is NaN, the result is the long integer representing the actual NaN value. 
*/



/** Turn a string into a 64-bit representation of the number in IEEE-754
    format. */

toIEEEBits[str] :=
{
   a = callJava["java.lang.Double", "doubleToRawLongBits", [callJava["java.lang.Double", "valueOf", [str]]]]
   if a < 0
      a = a + 2^64   // Convert signed long to unsigned.
   return a
}


/** Breaks a string representation of a floating-point number into the sign,
    exponent, and mantissa, normalized into traditional values.

    returns:
      [sign, exponent, mantissa]

    where:
      sign: a "normalized" sign bit, +1 for 0 or positive numbers,
                                     -1 for negative numbers.

      exponent:  a "normalized" exponent, which means that the mantissa is
                 multiplied by 2^exponent.

      mantissa:  a "normalized" mantissa, as an exact rational number.

    The exact representation of the number as the closest rational number can
    thus be easily obtained by:

    sign * mantissa * 2^exponent

    or by the toExactIEEE[str] function below.
*/

normalizedIEEEComponents[str] :=
{
   n = toIEEEBits[str]
   println["n=" + padLeft[(n->base2), 64, "0"]]
   signBit  = shiftRight[bitAnd[n, 0x8000000000000000], 63]
   sign = (-1)^signBit    // Normalize to +1 / -1
   expBits  = shiftRight[bitAnd[n, 0x7ff0000000000000], 52]
   mantissaBits = bitAnd[n, 0x000fffffffffffff]

   if (expBits == 0)
   {
      if (mantissaBits == 0)
      {
         // This is a signed zero.
         exponent = 0
         mantissa = 0
         sign = 1
      } else
      {
         // This is a subnormal.
         exponent = (1-1023)
         mantissa = mantissaBits/2^52
      }
   } else
   {
      // This is an ordinary number.
      exponent = expBits - 1023
      mantissa = 1 + mantissaBits/2^52
   }

   return[sign, exponent, mantissa]
}


/** Turns a string into a rational number indicating the exact value
    represented by the IEEE-754 representation. */

toExactIEEE[str] :=
{
   [sign, exponent, mantissa] = normalizedIEEEComponents[str]
   return sign * mantissa * 2^exponent
}


/** Returns the error in the IEEE-754 representation of a number, specified as
a string. */

IEEEError[str] :=
{
   frinkNum = eval[str]
   IEEENum = toExactIEEE[str]
   frinkRational = toRational[frinkNum]
   return frinkRational - IEEENum
}


View or download IEEE754.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 17645 days, 8 hours, 26 minutes ago.