/** 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 IEEENum - frinkRational }