12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811 |
- program bfloatfunc;
- {$mode objfpc}{$H+}
- uses
- SysUtils, Math;
- { Utility functions }
- function GetRealTime(const st: TSystemTime): Real;
- begin
- Result := st.Hour*3600.0 + st.Minute*60.0 + st.Second + st.MilliSecond/1000.0;
- end;
- {$push}
- {$warn 5057 off}
- function GetRealTime : Real;
- var
- st:TSystemTime;
- begin
- GetLocalTime(st);
- result:=GetRealTime(st);
- end;
- {$pop}
- function IIf(Condition: Boolean; TrueRes, FalseRes: Integer): Integer; inline;
- begin
- if Condition then
- Result := TrueRes
- else
- Result := FalseRes;
- end;
- const
- {$ifdef CONFORMANCE}
- ITERATIONS = $8;
- {$else}
- ITERATIONS = 33554432;
- {$endif}
- { TTestAncestor }
- type
- TTestAncestor = class
- private
- FStartTime: Real;
- FEndTime: Real;
- FAvgTime: Real;
- procedure SetStartTime;
- procedure SetEndTime;
- protected
- procedure DoTestIteration(Iteration: Integer); virtual; abstract;
- public
- constructor Create; virtual;
- destructor Destroy; override;
- procedure Run;
- function TestTitle: shortstring; virtual; abstract;
- function WriteResults: Boolean; virtual; abstract;
- property RunTime: Real read FAvgTime;
- end;
- TTestClass = class of TTestAncestor;
- TFloat32Test = class(TTestAncestor)
- protected
- FResultStorage: array[0..7] of Single;
- FExpected: array[0..7] of Single;
- class function IsEqual(Value, Reference: Single): Boolean; static;
- public
- function WriteResults: Boolean; override;
- end;
- TFloat32OneInputTest = class(TFloat32Test)
- protected
- FInputs: array[0..7] of Single;
- procedure DoTestIteration(Iteration: Integer); override;
- function DoFunc(Input: Single): Single; virtual; abstract;
- end;
- TFloat32TwoInputTest = class(TFloat32Test)
- protected
- FInputs: array[0..7] of array[0..1] of Single;
- procedure DoTestIteration(Iteration: Integer); override;
- function DoFunc(Input1, Input2: Single): Single; virtual; abstract;
- end;
-
- TSingleIntPair = record
- S: Single;
- N: Integer;
- end;
- TFloat32FloatIntTest = class(TFloat32Test)
- protected
- FInputs: array[0..7] of TSingleIntPair;
- procedure DoTestIteration(Iteration: Integer); override;
- function DoFunc(Float: Single; N: Integer): Single; virtual; abstract;
- end;
- TFloat64Test = class(TTestAncestor)
- protected
- FResultStorage: array[0..7] of Double;
- FExpected: array[0..7] of Double;
- class function IsEqual(Value, Reference: Double): Boolean; static;
- public
- function WriteResults: Boolean; override;
- end;
- TFloat64OneInputTest = class(TFloat64Test)
- protected
- FInputs: array[0..7] of Double;
- procedure DoTestIteration(Iteration: Integer); override;
- function DoFunc(Input: Double): Double; virtual; abstract;
- end;
- TFloat64TwoInputTest = class(TFloat64Test)
- protected
- FInputs: array[0..7] of array[0..1] of Double;
- procedure DoTestIteration(Iteration: Integer); override;
- function DoFunc(Input1, Input2: Double): Double; virtual; abstract;
- end;
-
- TDoubleIntPair = record
- D: Double;
- N: Integer;
- end;
- TFloat64FloatIntTest = class(TFloat64Test)
- protected
- FInputs: array[0..7] of TDoubleIntPair;
- procedure DoTestIteration(Iteration: Integer); override;
- function DoFunc(Float: Double; N: Integer): Double; virtual; abstract;
- end;
- { Test classes for actual tests }
- { 32-bit floating-point }
- TFloat32MinTest = class(TFloat32TwoInputTest)
- protected
- function DoFunc(Input1, Input2: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat32ImplicitMinTest = class(TFloat32MinTest)
- protected
- function DoFunc(Input1, Input2: Single): Single; override;
- public
- function TestTitle: shortstring; override;
- end;
- TFloat32MinSpecialTest = class(TFloat32MinTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat32ImplicitMinSpecialTest = class(TFloat32MinSpecialTest)
- protected
- function DoFunc(Input1, Input2: Single): Single; override;
- public
- function TestTitle: shortstring; override;
- end;
- TFloat32MaxTest = class(TFloat32TwoInputTest)
- protected
- function DoFunc(Input1, Input2: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat32ImplicitMaxTest = class(TFloat32MaxTest)
- protected
- function DoFunc(Input1, Input2: Single): Single; override;
- public
- function TestTitle: shortstring; override;
- end;
-
- TFloat32MaxSpecialTest = class(TFloat32MaxTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat32ImplicitMaxSpecialTest = class(TFloat32MaxSpecialTest)
- protected
- function DoFunc(Input1, Input2: Single): Single; override;
- public
- function TestTitle: shortstring; override;
- end;
-
- TFloat32SqrtTest = class(TFloat32OneInputTest)
- protected
- function DoFunc(Input: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32SqrtSpecialTest = class(TFloat32SqrtTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32LnTest = class(TFloat32OneInputTest)
- protected
- function DoFunc(Input: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32LnSpecialTest = class(TFloat32LnTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32ExpTest = class(TFloat32OneInputTest)
- protected
- function DoFunc(Input: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32ExpSpecialTest = class(TFloat32ExpTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32SinTest = class(TFloat32OneInputTest)
- protected
- function DoFunc(Input: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32SinSpecialTest = class(TFloat32SinTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32CosTest = class(TFloat32OneInputTest)
- protected
- function DoFunc(Input: Single): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat32CosSpecialTest = class(TFloat32CosTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat32LdexpTest = class(TFloat32FloatIntTest)
- protected
- function DoFunc(Float: Single; N: Integer): Single; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat32LdexpSpecialTest = class(TFloat32LdexpTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- { 64-bit floating-point }
- TFloat64MinTest = class(TFloat64TwoInputTest)
- protected
- function DoFunc(Input1, Input2: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat64ImplicitMinTest = class(TFloat64MinTest)
- protected
- function DoFunc(Input1, Input2: Double): Double; override;
- public
- function TestTitle: shortstring; override;
- end;
- TFloat64MinSpecialTest = class(TFloat64MinTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat64ImplicitMinSpecialTest = class(TFloat64MinSpecialTest)
- protected
- function DoFunc(Input1, Input2: Double): Double; override;
- public
- function TestTitle: shortstring; override;
- end;
- TFloat64MaxTest = class(TFloat64TwoInputTest)
- protected
- function DoFunc(Input1, Input2: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat64ImplicitMaxTest = class(TFloat64MaxTest)
- protected
- function DoFunc(Input1, Input2: Double): Double; override;
- public
- function TestTitle: shortstring; override;
- end;
-
- TFloat64MaxSpecialTest = class(TFloat64MaxTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat64ImplicitMaxSpecialTest = class(TFloat64MaxSpecialTest)
- protected
- function DoFunc(Input1, Input2: Double): Double; override;
- public
- function TestTitle: shortstring; override;
- end;
-
- TFloat64SqrtTest = class(TFloat64OneInputTest)
- protected
- function DoFunc(Input: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64SqrtSpecialTest = class(TFloat64SqrtTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64LnTest = class(TFloat64OneInputTest)
- protected
- function DoFunc(Input: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64LnSpecialTest = class(TFloat64LnTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64ExpTest = class(TFloat64OneInputTest)
- protected
- function DoFunc(Input: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64ExpSpecialTest = class(TFloat64ExpTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64SinTest = class(TFloat64OneInputTest)
- protected
- function DoFunc(Input: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64SinSpecialTest = class(TFloat64SinTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64CosTest = class(TFloat64OneInputTest)
- protected
- function DoFunc(Input: Double): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
-
- TFloat64CosSpecialTest = class(TFloat64CosTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat64LdexpTest = class(TFloat64FloatIntTest)
- protected
- function DoFunc(Float: Double; N: Integer): Double; override;
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- TFloat64LdexpSpecialTest = class(TFloat64LdexpTest)
- public
- constructor Create; override;
- function TestTitle: shortstring; override;
- end;
- { TTestAncestor }
- constructor TTestAncestor.Create;
- begin
- FStartTime := 0;
- FEndTime := 0;
- FAvgTime := 0;
- end;
- destructor TTestAncestor.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TTestAncestor.SetStartTime;
- begin
- FStartTime := GetRealTime();
- end;
- procedure TTestAncestor.SetEndTime;
- begin
- FEndTime := GetRealTime();
- if FEndTime < FStartTime then { Happens if the test runs past midnight }
- FEndTime := FEndTime + 86400.0;
- end;
- procedure TTestAncestor.Run;
- var
- X: Integer;
- begin
- SetStartTime;
- for X := 0 to ITERATIONS - 1 do
- DoTestIteration(X);
- SetEndTime;
- FAvgTime := FEndTime - FStartTime;
- end;
- { TFloat32Test }
- class function TFloat32Test.IsEqual(Value, Reference: Single): Boolean;
- var
- Epsilon: Single;
- begin
- if IsNan(Reference) then
- Exit(IsNan(Value))
- else if IsInfinite(Reference) then
- Exit(Value = Reference) { Must be the same infinity }
- else if Abs(Reference) < 0.25 then
- Epsilon := 0.00000095367431640625 { 2^-20 ~ 10^-6 }
- else
- Epsilon := Power(2, Floor(Ln(Reference) / Ln(2)) - 18);
- Result := Abs(Value - Reference) <= Epsilon; { If Value is NaN, Result will be set to False }
- end;
- function TFloat32Test.WriteResults: Boolean;
- var
- X: Byte;
- begin
- Result := True;
- for X := 0 to High(FResultStorage) do
- if not IsEqual(FResultStorage[X], FExpected[X]) then
- begin
- WriteLn('FAIL - index ', X, '; expected ', FExpected[X], ' got ', FResultStorage[X]);
- Result := False;
- Exit;
- end;
- end;
- { TFloat32OneInputTest }
- procedure TFloat32OneInputTest.DoTestIteration(Iteration: Integer);
- begin
- Iteration := Iteration and $7;
- FResultStorage[Iteration] := DoFunc(FInputs[Iteration]);
- end;
- { TFloat32TwoInputTest }
- procedure TFloat32TwoInputTest.DoTestIteration(Iteration: Integer);
- begin
- Iteration := Iteration and $7;
- FResultStorage[Iteration] := DoFunc(FInputs[Iteration][0], FInputs[Iteration][1]);
- end;
- { TFloat32FloatIntTest }
- procedure TFloat32FloatIntTest.DoTestIteration(Iteration: Integer);
- begin
- Iteration := Iteration and $7;
- FResultStorage[Iteration] := DoFunc(FInputs[Iteration].S, FInputs[Iteration].N);
- end;
- { TFloat32MinTest }
- const
- MINMAX_INPUTS: array[0..7] of array[0..1] of Single = (
- (-0.5, 0.5),
- (1048576.0, 1048577.0),
- (-1048576.0, -1048577.0),
- (0.0, -0.0),
- (0.0, 1E4),
- (0.0, -1E4),
- (0.0, 1E-4),
- (0.0, -1E-4)
- );
- MIN_EXPECTED: array[0..7] of Single = (
- -0.5,
- 1048576.0,
- -1048577.0,
- -0.0,
- 0.0,
- -1E4,
- 0.0,
- -1E-4
- );
-
- MAX_EXPECTED: array[0..7] of Single = (
- 0.5,
- 1048577.0,
- -1048576.0,
- -0.0,
- 1E4,
- 0.0,
- 1E-4,
- 0.0
- );
-
- constructor TFloat32MinTest.Create;
- begin
- inherited Create;
- Move(MINMAX_INPUTS, FInputs, SizeOf(FInputs));
- Move(MIN_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32MinTest.DoFunc(Input1, Input2: Single): Single;
- begin
- Result := Min(Input1, Input2);
- end;
-
- function TFloat32MinTest.TestTitle: shortstring;
- begin
- Result := 'Min (single-precision)';
- end;
- function TFloat32ImplicitMinTest.DoFunc(Input1, Input2: Single): Single;
- begin
- if Input1 < Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat32ImplicitMinTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Min (single-precision)';
- end;
- { TFloat32MaxTest }
- constructor TFloat32MaxTest.Create;
- begin
- inherited Create;
- Move(MINMAX_INPUTS, FInputs, SizeOf(FInputs));
- Move(MAX_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32MaxTest.DoFunc(Input1, Input2: Single): Single;
- begin
- Result := Max(Input1, Input2);
- end;
-
- function TFloat32MaxTest.TestTitle: shortstring;
- begin
- Result := 'Max (single-precision)';
- end;
- function TFloat32ImplicitMaxTest.DoFunc(Input1, Input2: Single): Single;
- begin
- if Input1 > Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat32ImplicitMaxTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Max (single-precision)';
- end;
- { TFloat32MinTest }
- const
- MINMAX_SPECIAL_INPUTS: array[0..7] of array[0..1] of Single = (
- (NaN, 0.0),
- (0.0, NaN),
- (0.0, Infinity),
- (Infinity, 0.0),
- (0.0, NegInfinity),
- (NegInfinity, 0.0),
- (Infinity, NegInfinity),
- (NegInfinity, Infinity)
- );
-
- MIN_SPECIAL_EXPECTED: array[0..7] of Single = (
- 0.0,
- NaN,
- 0.0,
- 0.0,
- NegInfinity,
- NegInfinity,
- NegInfinity,
- NegInfinity
- );
-
- MAX_SPECIAL_EXPECTED: array[0..7] of Single = (
- 0.0,
- NaN,
- Infinity,
- Infinity,
- 0.0,
- 0.0,
- Infinity,
- Infinity
- );
-
- constructor TFloat32MinSpecialTest.Create;
- begin
- inherited Create;
- Move(MINMAX_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(MIN_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32MinSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Min (special single-precision)';
- end;
- function TFloat32ImplicitMinSpecialTest.DoFunc(Input1, Input2: Single): Single;
- begin
- if Input1 < Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat32ImplicitMinSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Min (special single-precision)';
- end;
- { TFloat32MaxTest }
- constructor TFloat32MaxSpecialTest.Create;
- begin
- inherited Create;
- Move(MINMAX_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(MAX_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32MaxSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Max (special single-precision)';
- end;
- function TFloat32ImplicitMaxSpecialTest.DoFunc(Input1, Input2: Single): Single;
- begin
- if Input1 > Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat32ImplicitMaxSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Max (special single-precision)';
- end;
- { TFloat32SqrtTest }
- const
- SQRT_INPUTS: array[0..7] of Single = (
- 4.0,
- 1.0,
- 256.0,
- 2.0,
- 100.0,
- 0.5,
- 3.1415926535897932384626433832795, { Pi }
- 1.5707963267948966192313216916398 { Pi / 2 }
- );
-
- SQRT_EXPECTED: array[0..7] of Single = (
- 2.0,
- 1.0,
- 16.0,
- 1.414213562373095,
- 10.0,
- 0.707106781186548,
- 1.772453850905516,
- 1.253314137315500
- );
- constructor TFloat32SqrtTest.Create;
- begin
- inherited Create;
- Move(SQRT_INPUTS, FInputs, SizeOf(FInputs));
- Move(SQRT_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32SqrtTest.DoFunc(Input: Single): Single;
- begin
- Result := Sqrt(Input);
- end;
-
- function TFloat32SqrtTest.TestTitle: shortstring;
- begin
- Result := 'sqrt(x) (single-precision)';
- end;
- { TFloat32SqrtSpecialTest }
- const
- SQRT_SPECIAL_INPUTS: array[0..7] of Single = (
- 0.0,
- Infinity,
- NegInfinity,
- NaN,
- -0.0,
- -1.0,
- 1E6,
- NaN
- );
-
- SQRT_SPECIAL_EXPECTED: array[0..7] of Single = (
- 0.0,
- Infinity,
- NaN,
- NaN,
- 0.0,
- NaN,
- 1E3,
- NaN
- );
- constructor TFloat32SqrtSpecialTest.Create;
- begin
- inherited Create;
- Move(SQRT_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(SQRT_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32SqrtSpecialTest.TestTitle: shortstring;
- begin
- Result := 'sqrt(x) (special single-precision)';
- end;
- { TFloat32LnTest }
- const
- LN_EXPECTED: array[0..7] of Single = (
- 1.386294361119891,
- 0.0,
- 5.545177444479562,
- 0.693147180559945,
- 4.605170185988091,
- -0.693147180559945,
- 1.1447298858494002,
- 0.4515827052894549
- );
- constructor TFloat32LnTest.Create;
- begin
- inherited Create;
- Move(SQRT_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(LN_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32LnTest.DoFunc(Input: Single): Single;
- begin
- Result := Ln(Input);
- end;
-
- function TFloat32LnTest.TestTitle: shortstring;
- begin
- Result := 'ln x (single-precision)';
- end;
- { TFloat32LnSpecialTest }
- const
- LN_SPECIAL_EXPECTED: array[0..7] of Single = (
- NegInfinity,
- Infinity,
- NaN,
- NaN,
- NegInfinity,
- NaN,
- 13.815510557964274,
- NaN
- );
- constructor TFloat32LnSpecialTest.Create;
- begin
- inherited Create;
- Move(SQRT_SPECIAL_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(LN_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32LnSpecialTest.TestTitle: shortstring;
- begin
- Result := 'ln x (special single-precision)';
- end;
- { TFloat32ExpTest }
- const
- EXP_EXPECTED: array[0..7] of Single = (
- 54.598150033144239,
- 2.718281828459045,
- 1.5114276650041035e+111,
- 7.3890560989306502,
- 2.6881171418161354e+43,
- 1.6487212707001281,
- 23.1406926327792690,
- 4.8104773809653517
- );
- constructor TFloat32ExpTest.Create;
- begin
- inherited Create;
- Move(SQRT_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(EXP_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32ExpTest.DoFunc(Input: Single): Single;
- begin
- Result := Exp(Input);
- end;
-
- function TFloat32ExpTest.TestTitle: shortstring;
- begin
- Result := 'e^x (single-precision)';
- end;
- { TFloat32ExpSpecialTest }
- const
- EXP_SPECIAL_EXPECTED: array[0..7] of Single = (
- 1.0,
- Infinity,
- 0,
- NaN,
- 1.0,
- 0.3678794411714423,
- Infinity,
- NaN
- );
- constructor TFloat32ExpSpecialTest.Create;
- begin
- inherited Create;
- Move(SQRT_SPECIAL_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(EXP_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32ExpSpecialTest.TestTitle: shortstring;
- begin
- Result := 'e^x (special single-precision)';
- end;
- { TFloat32SinTest }
- const
- SIN_EXPECTED: array[0..7] of Single = (
- -0.756802495307928,
- 0.841470984807897,
- -0.999208034107063,
- 0.9092974268256817,
- -0.5063656411097588,
- 0.4794255386042030,
- 0.0,
- 1.0
- );
- constructor TFloat32SinTest.Create;
- begin
- inherited Create;
- Move(SQRT_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(SIN_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32SinTest.DoFunc(Input: Single): Single;
- begin
- Result := Sin(Input);
- end;
-
- function TFloat32SinTest.TestTitle: shortstring;
- begin
- Result := 'sin x (single-precision)';
- end;
- { TFloat32SinSpecialTest }
- const
- SIN_SPECIAL_INPUTS: array[0..7] of Single = ( { Using different inputs as infinities are invalid }
- 0.0,
- -1.0,
- 1E6,
- NaN,
- -0.0,
- -1.0,
- 1E6,
- NaN
- );
- SIN_SPECIAL_EXPECTED: array[0..7] of Single = (
- 0.0,
- -0.8414709848078965,
- -0.3499935021712930,
- NaN,
- -0.0,
- -0.8414709848078965,
- -0.3499935021712930,
- NaN
- );
- constructor TFloat32SinSpecialTest.Create;
- begin
- inherited Create;
- Move(SIN_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(SIN_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32SinSpecialTest.TestTitle: shortstring;
- begin
- Result := 'sin x (special single-precision)';
- end;
- { TFloat32CosTest }
- const
- COS_EXPECTED: array[0..7] of Single = (
- -0.6536436208636119,
- 0.5403023058681397,
- -0.0397907599311577,
- -0.4161468365471424,
- 0.8623188722876839,
- 0.8775825618903727,
- -1.0, { Pi }
- 0.0
- );
- constructor TFloat32CosTest.Create;
- begin
- inherited Create;
- Move(SQRT_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(COS_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32CosTest.DoFunc(Input: Single): Single;
- begin
- Result := Cos(Input);
- end;
-
- function TFloat32CosTest.TestTitle: shortstring;
- begin
- Result := 'cos x (single-precision)';
- end;
- { TFloat32SinSpecialTest }
- const
- COS_SPECIAL_EXPECTED: array[0..7] of Single = (
- 1.0,
- 0.5403023058681397,
- 0.9367521275331448,
- NaN,
- 1.0,
- 0.5403023058681397,
- 0.9367521275331448,
- NaN
- );
- constructor TFloat32CosSpecialTest.Create;
- begin
- inherited Create;
- Move(SIN_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(COS_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat32CosSpecialTest.TestTitle: shortstring;
- begin
- Result := 'cos x (special single-precision)';
- end;
- { TFloat32LdexpTest }
- const
- LDEXP_INPUTS: array[0..7] of TSingleIntPair = (
- (S: 1.0; N: 0),
- (S: 2.7182818284590452353602874713527; N: -1),
- (S: 0.85309609426787873559547283129472; N: 6),
- (S: 0.1; N: 1),
- (S: 0.2; N: 2),
- (S: 0.3; N: 3),
- (S: 0.4; N: 4),
- (S: 0.5; N: 5)
- );
- LDEXP_EXPECTED: array[0..7] of Single = (
- 1.0,
- 1.3591409142295226176801437356763,
- 54.598150033144239078110261202862,
- 0.2,
- 0.8,
- 2.4,
- 6.4,
- 16.0
- );
- constructor TFloat32LdexpTest.Create;
- begin
- inherited Create;
- Move(LDEXP_INPUTS, FInputs, SizeOf(FInputs));
- Move(LDEXP_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32LdexpTest.DoFunc(Float: Single; N: Integer): Single;
- begin
- Result := LdExp(Float, N);
- end;
- function TFloat32LdexpTest.TestTitle: shortstring;
- begin
- Result := 'ldexp(x, n) (single-precision)';
- end;
- { TFloat32SpecialLdexpTest }
- const
- LDEXP_SPECIAL_INPUTS: array[0..7] of TSingleIntPair = (
- (S: Infinity; N: 0),
- (S: NegInfinity; N: 0),
- (S: 2.0; N: -128),
- (S: 2.0; N: 127),
- (S: NaN; N: 1),
- (S: 0.0; N: 16384),
- (S: 1.7014118346046923173168730371588e+38; N: -128),
- (S: 2.9387358770557187699218413430556e-39; N: 127)
- );
- LDEXP_SPECIAL_EXPECTED: array[0..7] of Single = (
- Infinity,
- NegInfinity,
- 2.9387358770557187699218413430556e-39,
- Infinity,
- Nan,
- 0.0,
- 0.5,
- 0.5
- );
- constructor TFloat32LdexpSpecialTest.Create;
- begin
- inherited Create;
- Move(LDEXP_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(LDEXP_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat32LdexpSpecialTest.TestTitle: shortstring;
- begin
- Result := 'ldexp(x, n) (special single-precision)';
- end;
- { TFloat64Test }
- class function TFloat64Test.IsEqual(Value, Reference: Double): Boolean;
- var
- Epsilon: Double;
- begin
- if IsNan(Reference) then
- Exit(IsNan(Value))
- else if IsInfinite(Reference) then
- Exit(Value = Reference)
- else if Abs(Reference) < 0.25 then
- Epsilon := 9.094947017729282379150390625e-13 { 2^-40 ~ 10^-12 }
- else
- Epsilon := Power(2, Floor(Ln(Reference) / Ln(2)) - 18);
- Result := Abs(Value - Reference) <= Epsilon;
- end;
- function TFloat64Test.WriteResults: Boolean;
- var
- X: Byte;
- begin
- Result := True;
- for X := 0 to High(FResultStorage) do
- if not IsEqual(FResultStorage[X], FExpected[X]) then
- begin
- WriteLn('FAIL - index ', X, '; expected ', FExpected[X], ' got ', FResultStorage[X]);
- Result := False;
- Exit;
- end;
- end;
- { TFloat64OneInputTest }
- procedure TFloat64OneInputTest.DoTestIteration(Iteration: Integer);
- begin
- Iteration := Iteration and $7;
- FResultStorage[Iteration] := DoFunc(FInputs[Iteration]);
- end;
- { TFloat64TwoInputTest }
- procedure TFloat64TwoInputTest.DoTestIteration(Iteration: Integer);
- begin
- Iteration := Iteration and $7;
- FResultStorage[Iteration] := DoFunc(FInputs[Iteration][0], FInputs[Iteration][1]);
- end;
- { TFloat64FloatIntTest }
- procedure TFloat64FloatIntTest.DoTestIteration(Iteration: Integer);
- begin
- Iteration := Iteration and $7;
- FResultStorage[Iteration] := DoFunc(FInputs[Iteration].D, FInputs[Iteration].N);
- end;
- { TFloat64MinTest }
- const
- MINMAX_64_INPUTS: array[0..7] of array[0..1] of Double = (
- (-0.5, 0.5),
- (1048576.0, 1048577.0),
- (-1048576.0, -1048577.0),
- (0.0, -0.0),
- (0.0, 1E4),
- (0.0, -1E4),
- (0.0, 1E-4),
- (0.0, -1E-4)
- );
- MIN_64_EXPECTED: array[0..7] of Double = (
- -0.5,
- 1048576.0,
- -1048577.0,
- -0.0,
- 0.0,
- -1E4,
- 0.0,
- -1E-4
- );
-
- MAX_64_EXPECTED: array[0..7] of Double = (
- 0.5,
- 1048577.0,
- -1048576.0,
- -0.0,
- 1E4,
- 0.0,
- 1E-4,
- 0.0
- );
-
- constructor TFloat64MinTest.Create;
- begin
- inherited Create;
- Move(MINMAX_64_INPUTS, FInputs, SizeOf(FInputs));
- Move(MIN_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64MinTest.DoFunc(Input1, Input2: Double): Double;
- begin
- Result := Min(Input1, Input2);
- end;
-
- function TFloat64MinTest.TestTitle: shortstring;
- begin
- Result := 'Min (double-precision)';
- end;
- function TFloat64ImplicitMinTest.DoFunc(Input1, Input2: Double): Double;
- begin
- if Input1 < Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat64ImplicitMinTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Min (double-precision)';
- end;
- { TFloat64MaxTest }
- constructor TFloat64MaxTest.Create;
- begin
- inherited Create;
- Move(MINMAX_64_INPUTS, FInputs, SizeOf(FInputs));
- Move(MAX_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64MaxTest.DoFunc(Input1, Input2: Double): Double;
- begin
- Result := Max(Input1, Input2);
- end;
-
- function TFloat64MaxTest.TestTitle: shortstring;
- begin
- Result := 'Max (double-precision)';
- end;
- function TFloat64ImplicitMaxTest.DoFunc(Input1, Input2: Double): Double;
- begin
- if Input1 > Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat64ImplicitMaxTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Max (double-precision)';
- end;
- { TFloat64MinTest }
- const
- MINMAX_64_SPECIAL_INPUTS: array[0..7] of array[0..1] of Double = (
- (NaN, 0.0),
- (0.0, NaN),
- (0.0, Infinity),
- (Infinity, 0.0),
- (0.0, NegInfinity),
- (NegInfinity, 0.0),
- (Infinity, NegInfinity),
- (NegInfinity, Infinity)
- );
-
- MIN_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- 0.0,
- NaN,
- 0.0,
- 0.0,
- NegInfinity,
- NegInfinity,
- NegInfinity,
- NegInfinity
- );
-
- MAX_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- 0.0,
- NaN,
- Infinity,
- Infinity,
- 0.0,
- 0.0,
- Infinity,
- Infinity
- );
-
- constructor TFloat64MinSpecialTest.Create;
- begin
- inherited Create;
- Move(MINMAX_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(MIN_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64MinSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Min (special double-precision)';
- end;
- function TFloat64ImplicitMinSpecialTest.DoFunc(Input1, Input2: Double): Double;
- begin
- if Input1 < Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat64ImplicitMinSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Min (special double-precision)';
- end;
- { TFloat64MaxTest }
- constructor TFloat64MaxSpecialTest.Create;
- begin
- inherited Create;
- Move(MINMAX_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(MAX_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64MaxSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Max (special double-precision)';
- end;
- function TFloat64ImplicitMaxSpecialTest.DoFunc(Input1, Input2: Double): Double;
- begin
- if Input1 > Input2 then
- Result := Input1
- else
- Result := Input2;
- end;
-
- function TFloat64ImplicitMaxSpecialTest.TestTitle: shortstring;
- begin
- Result := 'Implicit Max (special double-precision)';
- end;
- { TFloat64SqrtTest }
- const
- SQRT_64_INPUTS: array[0..7] of Double = (
- 4.0,
- 1.0,
- 256.0,
- 2.0,
- 100.0,
- 0.5,
- 3.1415926535897932384626433832795, { Pi }
- 1.5707963267948966192313216916398 { Pi / 2 }
- );
-
- SQRT_64_EXPECTED: array[0..7] of Double = (
- 2.0,
- 1.0,
- 16.0,
- 1.4142135623730950488016887242097,
- 10.0,
- 0.70710678118654752440084436210485,
- 1.7724538509055160272981674833411,
- 1.2533141373155002512078826424055
- );
- constructor TFloat64SqrtTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_INPUTS, FInputs, SizeOf(FInputs));
- Move(SQRT_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64SqrtTest.DoFunc(Input: Double): Double;
- begin
- Result := Sqrt(Input);
- end;
-
- function TFloat64SqrtTest.TestTitle: shortstring;
- begin
- Result := 'sqrt(x) (double-precision)';
- end;
- { TFloat64SqrtSpecialTest }
- const
- SQRT_64_SPECIAL_INPUTS: array[0..7] of Double = (
- 0.0,
- Infinity,
- NegInfinity,
- NaN,
- -0.0,
- -1.0,
- 1E6,
- NaN
- );
-
- SQRT_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- 0.0,
- Infinity,
- NaN,
- NaN,
- 0.0,
- NaN,
- 1E3,
- NaN
- );
- constructor TFloat64SqrtSpecialTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(SQRT_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64SqrtSpecialTest.TestTitle: shortstring;
- begin
- Result := 'sqrt(x) (special double-precision)';
- end;
- { TFloat64LnTest }
- const
- LN_64_EXPECTED: array[0..7] of Double = (
- 1.3862943611198906188344642429164,
- 0.0,
- 5.5451774444795624753378569716654,
- 0.69314718055994530941723212145818,
- 4.6051701859880913680359829093687,
- -0.69314718055994530941723212145818,
- 1.1447298858494001741434273513531,
- 0.45158270528945486472619522989488
- );
- constructor TFloat64LnTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(LN_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64LnTest.DoFunc(Input: Double): Double;
- begin
- Result := Ln(Input);
- end;
-
- function TFloat64LnTest.TestTitle: shortstring;
- begin
- Result := 'ln x (double-precision)';
- end;
- { TFloat64LnSpecialTest }
- const
- LN_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- NegInfinity,
- Infinity,
- NaN,
- NaN,
- NegInfinity,
- NaN,
- 13.815510557964274104107948728106,
- NaN
- );
- constructor TFloat64LnSpecialTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(LN_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64LnSpecialTest.TestTitle: shortstring;
- begin
- Result := 'ln x (special double-precision)';
- end;
- { TFloat64ExpTest }
- const
- EXP_64_EXPECTED: array[0..7] of Double = (
- 54.598150033144239078110261202861,
- 2.7182818284590455, // remove the last 5 and append 2353602874713527 (too precise),
- 1.5114276650041035425200896657073e+111,
- 7.389056098930650227230427460575,
- 2.68811714181613544841262555158e+43,
- 1.6487212707001281468486507878142,
- 23.140692632779269005729086367949,
- 4.8104773809653516554730356667038
- );
- constructor TFloat64ExpTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(EXP_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64ExpTest.DoFunc(Input: Double): Double;
- begin
- Result := Exp(Input);
- end;
-
- function TFloat64ExpTest.TestTitle: shortstring;
- begin
- Result := 'e^x (double-precision)';
- end;
- { TFloat64ExpSpecialTest }
- const
- EXP_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- 1.0,
- Infinity,
- 0,
- NaN,
- 1.0,
- 0.36787944117144232159552377016146,
- Infinity,
- NaN
- );
- constructor TFloat64ExpSpecialTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(EXP_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64ExpSpecialTest.TestTitle: shortstring;
- begin
- Result := 'e^x (special double-precision)';
- end;
- { TFloat64SinTest }
- const
- SIN_64_EXPECTED: array[0..7] of Double = (
- -0.75680249530792825137263909451183,
- 0.8414709848078965066525023216303,
- -0.99920803410706269906759056238387,
- 0.90929742682568169539601986591174,
- -0.50636564110975879365655761045979,
- 0.47942553860420300027328793521557,
- 0.0,
- 1.0
- );
- constructor TFloat64SinTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(SIN_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64SinTest.DoFunc(Input: Double): Double;
- begin
- Result := Sin(Input);
- end;
-
- function TFloat64SinTest.TestTitle: shortstring;
- begin
- Result := 'sin x (single-precision)';
- end;
- { TFloat64SinSpecialTest }
- const
- SIN_64_SPECIAL_INPUTS: array[0..7] of Double = ( { Using different inputs as infinities are invalid }
- 0.0,
- -1.0,
- 1E6,
- NaN,
- -0.0,
- -1.0,
- 1E6,
- NaN
- );
- SIN_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- 0.0,
- -0.8414709848078965066525023216303,
- -0.34999350217129295211765248678077,
- NaN,
- -0.0,
- -0.8414709848078965066525023216303,
- -0.34999350217129295211765248678077,
- NaN
- );
- constructor TFloat64SinSpecialTest.Create;
- begin
- inherited Create;
- Move(SIN_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(SIN_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64SinSpecialTest.TestTitle: shortstring;
- begin
- Result := 'sin x (double single-precision)';
- end;
- { TFloat64CosTest }
- const
- COS_64_EXPECTED: array[0..7] of Double = (
- -0.65364362086361191463916818309775,
- 0.54030230586813971740093660744298,
- -0.03979075993115770952448155799687,
- -0.41614683654714238699756822950076,
- 0.86231887228768393410193851395084,
- 0.87758256189037271611628158260383,
- -1.0, { Pi }
- 0.0
- );
- constructor TFloat64CosTest.Create;
- begin
- inherited Create;
- Move(SQRT_64_INPUTS, FInputs, SizeOf(FInputs)); { Reuse the sqrt inputs }
- Move(COS_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64CosTest.DoFunc(Input: Double): Double;
- begin
- Result := Cos(Input);
- end;
-
- function TFloat64CosTest.TestTitle: shortstring;
- begin
- Result := 'cos x (double-precision)';
- end;
- { TFloat64CosSpecialTest }
- const
- COS_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- 1.0,
- 0.54030230586813971740093660744298,
- 0.93675212753314478693853253507492,
- NaN,
- 1.0,
- 0.54030230586813971740093660744298,
- 0.93675212753314478693853253507492,
- NaN
- );
- constructor TFloat64CosSpecialTest.Create;
- begin
- inherited Create;
- Move(SIN_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(COS_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
-
- function TFloat64CosSpecialTest.TestTitle: shortstring;
- begin
- Result := 'cos x (special double-precision)';
- end;
- { TFloat64LdexpTest }
- const
- LDEXP_64_INPUTS: array[0..7] of TDoubleIntPair = (
- (D: 1.0; N: 0),
- (D: 2.7182818284590452353602874713527; N: -1),
- (D: 0.85309609426787873559547283129472; N: 6),
- (D: 0.1; N: 1),
- (D: 0.2; N: 2),
- (D: 0.3; N: 3),
- (D: 0.4; N: 4),
- (D: 0.5; N: 5)
- );
- LDEXP_64_EXPECTED: array[0..7] of Double = (
- 1.0,
- 1.3591409142295226176801437356763,
- 54.598150033144239078110261202862,
- 0.2,
- 0.8,
- 2.4,
- 6.4,
- 16.0
- );
- constructor TFloat64LdexpTest.Create;
- begin
- inherited Create;
- Move(LDEXP_64_INPUTS, FInputs, SizeOf(FInputs));
- Move(LDEXP_64_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64LdexpTest.DoFunc(Float: Double; N: Integer): Double;
- begin
- Result := LdExp(Float, N);
- end;
- function TFloat64LdexpTest.TestTitle: shortstring;
- begin
- Result := 'ldexp(x, n) (double-precision)';
- end;
- { TFloat32SpecialLdexpTest }
- const
- LDEXP_64_SPECIAL_INPUTS: array[0..7] of TDoubleIntPair = (
- (D: Infinity; N: 0),
- (D: NegInfinity; N: 0),
- (D: 2.0; N: -1024),
- (D: 2.0; N: 1023),
- (D: NaN; N: 1),
- (D: 0.0; N: 16384),
- (D: 8.9884656743115795386465259539451e+307; N: -1024),
- (D: 5.562684646268003457725581793331e-309; N: 1023)
- );
- LDEXP_64_SPECIAL_EXPECTED: array[0..7] of Double = (
- Infinity,
- NegInfinity,
- 5.562684646268003457725581793331e-309,
- Infinity,
- Nan,
- 0.0,
- 0.5,
- 0.5
- );
- constructor TFloat64LdexpSpecialTest.Create;
- begin
- inherited Create;
- Move(LDEXP_64_SPECIAL_INPUTS, FInputs, SizeOf(FInputs));
- Move(LDEXP_64_SPECIAL_EXPECTED, FExpected, SizeOf(FExpected));
- end;
- function TFloat64LdexpSpecialTest.TestTitle: shortstring;
- begin
- Result := 'ldexp(x, n) (special double-precision)';
- end;
- { Main function }
- const
- { TCompleteByteRange and descendants }
- TestClasses: array[0..39] of TTestClass = (
- TFloat32MinTest,
- TFloat32MaxTest,
- TFloat32ImplicitMinTest,
- TFloat32ImplicitMaxTest,
- TFloat32MinSpecialTest,
- TFloat32MaxSpecialTest,
- TFloat32ImplicitMinSpecialTest,
- TFloat32ImplicitMaxSpecialTest,
- TFloat32SqrtTest,
- TFloat32SqrtSpecialTest,
- TFloat32LnTest,
- TFloat32LnSpecialTest,
- TFloat32ExpTest,
- TFloat32ExpSpecialTest,
- TFloat32SinTest,
- TFloat32SinSpecialTest,
- TFloat32CosTest,
- TFloat32CosSpecialTest,
- TFloat32LdexpTest,
- TFloat32LdexpSpecialTest,
- TFloat64MinTest,
- TFloat64MaxTest,
- TFloat64ImplicitMinTest,
- TFloat64ImplicitMaxTest,
- TFloat64MinSpecialTest,
- TFloat64MaxSpecialTest,
- TFloat64ImplicitMinSpecialTest,
- TFloat64ImplicitMaxSpecialTest,
- TFloat64SqrtTest,
- TFloat64SqrtSpecialTest,
- TFloat64LnTest,
- TFloat64LnSpecialTest,
- TFloat64ExpTest,
- TFloat64ExpSpecialTest,
- TFloat64SinTest,
- TFloat64SinSpecialTest,
- TFloat64CosTest,
- TFloat64CosSpecialTest,
- TFloat64LdexpTest,
- TFloat64LdexpSpecialTest
- );
- var
- CurrentObject: TTestAncestor;
- Failed: Boolean;
- X: Integer;
- SummedUpAverageDuration, AverageDuration : Double;
- begin
- SetExceptionMask(GetExceptionMask + [exOverflow, exZeroDivide, exInvalidOp]);
- SummedUpAverageDuration := 0.0;
- Failed := False;
- WriteLn('Floating-point compilation and timing test');
- WriteLn('------------------------------------------');
- for X := low(TestClasses) to High(TestClasses) do
- begin
- try
- CurrentObject := TestClasses[X].Create;
- try
- Write(CurrentObject.TestTitle:40, ' - ');
- CurrentObject.Run;
- if CurrentObject.WriteResults then
- begin
- {$ifdef CONFORMANCE}
- WriteLn('Pass');
- {$else CONFORMANCE}
- AverageDuration := ((CurrentObject.RunTime * 1000000000.0) / ITERATIONS);
- WriteLn('Pass - average iteration duration: ', AverageDuration:1:3, ' ns');
- SummedUpAverageDuration := SummedUpAverageDuration + AverageDuration;
- {$endif CONFORMANCE}
- end
- else
- { Final average isn't processed if a test failed, so there's no need
- to calculate and add the average duration to it }
- Failed := True;
- finally
- CurrentObject.Free;
- end;
- except on E: Exception do
- begin
- WriteLn('Exception "', E.ClassName, '" raised while running test object of class "', TestClasses[X].ClassName, '"');
- Failed := True;
- end;
- end;
- end;
- if Failed then
- Halt(1);
- {$ifdef CONFORMANCE}
- WriteLn(#10'ok');
- {$else CONFORMANCE}
- WriteLn(#10'- Sum of average durations: ', SummedUpAverageDuration:1:3, ' ns');
- WriteLn('- Overall average duration: ', (SummedUpAverageDuration / Length(TestClasses)):1:3, ' ns');
- {$endif CONFORMANCE}
- end.
|