MantissaAndExponent
New to Analytica 5.2
The MantissaAndExponent function is used to examine the internals of a floating-point number. This is sometimes useful when debugging difficult numeric round-off problems.
MantissaAndExponent( x, integerMantissa)
Returns the mantissa and base-2 exponent of a floating-point number. The function has two return values, so you need to capture them using the syntax
Local (mantissa, exponent) := MantissaAndExponent(x)
The return values are such that «x» is exactly equal to mantissa * 2^exponent
. The sign of the mantissa matches the sign of «x».
When the optional «integerMantissa» is omitted or False
, then exponent is an integer and for any finite non-zero «x», [math]\displaystyle{ 0.5 \le mantissa \lt 1 }[/math]. This variation is equivalent to the frexp(x)
function found in many other programming languages.
When «integerMantissa» is True
, the mantissa is an integer, [math]\displaystyle{ -2^{53} \lt mantissa \lt 2^{53} }[/math], and exponent in an integer or is NaN when «x» is NaN. The exponent returned will usually be smaller by 53 (the number of bits in the mantissa) than the exponent returned when integerMantissa:True
is not specified.
Edge cases
The following table describes the various special cases that can arise, and the representation returned in both usage cases.
Real mantissa | Integer mantissa | |||
---|---|---|---|---|
«x» | mantissa | exponent | mantissa | exponent |
0 (zero) | 0 | 0 | 0 | 0 |
Inf | Inf | -1 | 2^52 | 972 |
-Inf | -Inf | -1 | -2^52 | 972 |
NaN | NaN | -1 | «nan code» | NaN |
Ordinary (normalized) number |
[math]\displaystyle{ 0.5 \le m \lt 1.0 }[/math] | [math]\displaystyle{ -1021 \le e \le 1024 }[/math] | [math]\displaystyle{ 2^{52} \le |m| \lt 2^{53} }[/math] | [math]\displaystyle{ -971 \le e \le -1074 }[/math] |
Sub-normalized number |
[math]\displaystyle{ 0.5 \le m \lt 1.0 }[/math] | [math]\displaystyle{ -1073 \le e \lt -1021 }[/math] | [math]\displaystyle{ -2^{-52} \lt m \lt 2^{52} }[/math] | [math]\displaystyle{ -1074 }[/math] |
Floating point from Mantissa and Exponent
To obtain a floating point number from a mantissa and exponent, the simple expression
mantissa * 2^exponent
returns the corresponding floating point number except in the case where exponent=1024
. The problem in the 1024 case is that 2^1024 exceeds the maximum representable finite floating-point number, so 2^exponent
overflows to INF, resulting in INF. Because 0.5 <= mantissa < 1, the true number is actually finite. The 1024 case does not occur when using integerMantissa:True
, so for that usage the simple expression is sufficient.
To handle the full case, you can introduce the following User-Defined Function:
- Function
Ldexp(mantissa, exponent)
- Definition:
Next representable float
In some cases it may be convenient to obtain the smallest representable number than is strictly greater than a given value x. This might be denoted as [math]\displaystyle{ x+\epsilon }[/math]. In Analytica 6.3, the function NextFloatToward returns this value. Prior to Analytica 6.3, this can be obtained using the following User-Defined Function:
- Function
NextFloat(x)
- Definition:
If x=0 Then 2^-1074 Else
Local (mant,e) := MantissaAndExponent(x,true) Do (mant+1)*2^e
Similarly, this UDF gives the largest representable floating point number that is strictly less than x (i.e., [math]\displaystyle{ x - \epsilon }[/math]):
- Function
PrevFloat(x)
- Definition:
If x=0 Then -2^-1074 Else
Local (mant,e) := MantissaAndExponent(x,true) Do (mant-1)*2^e
The following edge-cases work as one would expect:
NextFloat(NaN)
→ NaNPrevFloat(NaN)
→ NaNNextFloat(Inf)
→ InfPrevFloat(Inf)
→ 1.797693134862316e+308 { i.e., largest finite float }NextFloat(-Inf)
→ -1.797693134862316e+308 {i.e., smallest finite float }PrevFloat(-Inf)
→ -InfNextFloat(0)
→ 4.9406564584124654e-324 { i.e., smallest positive float }PrevFloat(0)
→ -4.9406564584124654e-324 { i.e., largest negative float }NextFloat(Null)
→ NullPrevFloat(Null)
→ Null
Enable comment auto-refresher