Background
I want to create a unit test to test some rtl aspects of Delphi, and in order to do this I want to use very specific IEEE floating point values that I want to create directly from their binary representation.
I have come up so far with this routine, and it actually does the job.
function TestIEEEDouble.BuildDoubleFromRawInt64(const aBinData:UInt64):double;
begin
CheckEquals(sizeof(aBinData),sizeof(Result),'sizeof(aBinData),Sizeof(Result)'); // ensures we dont mess up with wrong types
Move(aBinData,Result,sizeof(Result));
end;
It is used as follows (bindata may still be wrong, but thats not the question):
procedure TestIEEEDouble.Setup;
begin
inherited;
FSmallestPositiveDouble:=BuildDoubleFromRawInt64($0000000000000001);
FSmallestNegativeDouble:=BuildDoubleFromRawInt64($8000000000000001);
FLargestPositiveDouble :=BuildDoubleFromRawInt64($7FEFFFFFFFFFFFFF);
FLargestNegativeDouble :=BuildDoubleFromRawInt64($8FEFFFFFFFFFFFFF);
end;
Question
Is there syntax that would allow creating a const double
directly from a binary (hex) representation looking something like this:
const
cSmallestPositiveDouble:double=double($0000000000000001);
Where the result obviously should NOT be 1.0
(it is with this syntax) but (close to) 4.94065645841247e-324
To answer with my own initial solution, the syntax is a bit more extensive than I like, but this seems to do the trick using a variant record and implicit type casting.
Nice feature/side effect is that you can quickly see binary representation and double representation together in the inspector/watchwindow.
type
RDoubleHelperRec=record
class operator Implicit(aRec:RDoubleHelperRec):double;
case Bin:boolean of
True:
(BinData:UINT64);
False:
(DoubleData:double);
end;
...
class operator RDoubleHelperRec.Implicit(aRec: RDoubleHelperRec): double;
begin
Result:=aRec.DoubleData;
end;
then when using it, declare as const:
procedure TestIEEEDouble.TestCompareValueBoundary;
const
cSmallestPositiveDouble:RDoubleHelperRec=(BinData:$0000000000000001);
begin
CheckEquals(0,CompareValue(FSmallestPositiveDouble,cSmallestPositiveDouble),'CompareValue(FSmallestPositiveDouble,cSmallestPositiveDouble)');
end;