Title: Missing Values: Implemeting and testing
Question: How to define a NaN bit pattern as a double precission value and how to test if a double is NaN
Answer:
{The following unit implements two NaN (not a number) patterns that can be assigned to variables declared as doubles. I use these patterns for missing values in a data stream. When I process the data stream I need to know wheter
a specific sample is a missing value or not. IsNan is a general test for NaN}
unit NaNs;
interface
const
//define to bit patterns that are not numbers
NaNp:double=0; // + not a number
NaNm:double=0; // - not a number
FUNCTION IsNaN(x:double):Boolean;
implementation
const
//mask for condition register
cCond0Mask = $0100;
cCond1Mask = $0200;
cCond2Mask = $0400;
cCond3Mask = $4000;
cCondAllMask= $4700;
cUnsupP = $0000;
cUnsupM = $0200;
cNanP = $0100;
cNanM = $0300;
cNormalP = $0400;
cNormalM = $0600;
cInfnityP = $0500;
cInfnityM = $0700;
cZeroP = $4000;
cZeroM = $4200;
cEmptyP = $4100;
cEmptyM = $4300;
cDenormalP = $4400;
cDenormalM = $4600;
FUNCTION IsNaN(x:double):Boolean;
{True if value is not a number}
VAR
stw:Word;
BEGIN
Asm
{load a}
Fld x
{examine number}
FXAM
FNSTSW stw
{restore stack state}
FFREE ST(0)
END;
{mask out c0..c3}
Stw:=stw and cCondAllMask;
IsNaN:=(stw =cNaNP) or (stw=cNanM);
END{IsNaN};
type
IcastDbl = record
HiLW,LoLW:longword;
end;
initialization
//there is a class of NaNs we use just two of them,
//a positive and a negative one
IcastDbl(NaNp).LoLW:=$7fff0000;
IcastDbl(NaNm).LoLW:=$ffff0000;
end.