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