|
@@ -0,0 +1,121 @@
|
|
|
+{ this test is geared towards Double values }
|
|
|
+
|
|
|
+program tb0643;
|
|
|
+
|
|
|
+{$mode objfpc}
|
|
|
+
|
|
|
+uses
|
|
|
+ Math, sysutils;
|
|
|
+
|
|
|
+type
|
|
|
+ TDataset = record
|
|
|
+ Value: Double;
|
|
|
+ AsIs: Double;
|
|
|
+ More: Double;
|
|
|
+ Less: Double;
|
|
|
+ Exc: Boolean;
|
|
|
+ end;
|
|
|
+
|
|
|
+var
|
|
|
+ DataSet: array[0..15] of TDataset = (
|
|
|
+ (Value: 1.5; AsIs: 0.5; More: 0; Less: 0; Exc: False),
|
|
|
+ (Value: 0; AsIs: 0; More: 0.5; Less: -0.5; Exc: False),
|
|
|
+ (Value: 2251799813685248; AsIs: 0; More: 0.5; Less: 0.5; Exc: False),
|
|
|
+ (Value: 4503599627370496; AsIs: 0; More: 0; Less: 0.5; Exc: False),
|
|
|
+ (Value: 1E300; AsIs: 0; More: 0; Less: 0; Exc: False),
|
|
|
+ (Value: 0.125; AsIs: 0.125; More: 0.625; Less: -0.375; Exc: False),
|
|
|
+ (Value: 3.6415926535897932384626433832795; AsIs: 0.64159265358979312; More: 0.14159265358979312; Less: 0.14159265358979312; Exc: False),
|
|
|
+ (Value: -1.5; AsIs: -0.5; More: 0; Less: 0; Exc: False),
|
|
|
+ (Value: -2251799813685248; AsIs: 0; More: -0.5; Less: -0.5; Exc: False),
|
|
|
+ (Value: -4503599627370496; AsIs: 0; More: -0.5; Less: 0; Exc: False),
|
|
|
+ (Value: -1E300; AsIs: 0; More: 0; Less: 0; Exc: False),
|
|
|
+ (Value: -0.125; AsIs: -0.125; More: 0.375; Less: -0.625; Exc: False),
|
|
|
+ (Value: -3.6415926535897932384626433832795; AsIs: -0.64159265358979312; More: -0.14159265358979312; Less: -0.14159265358979312; Exc: False),
|
|
|
+ (Value: Infinity; AsIs: NaN; More: NaN; Less: NaN; Exc: True),
|
|
|
+ (Value: NegInfinity; AsIs: NaN; More: NaN; Less: NaN; Exc: True),
|
|
|
+ (Value: NaN; AsIs: NaN; More: NaN; Less: NaN; Exc: False)
|
|
|
+ );
|
|
|
+
|
|
|
+function SameValue(aGot, aExpected: Double): Boolean;
|
|
|
+begin
|
|
|
+ if IsNan(aExpected) then
|
|
|
+ Result := IsNan(aGot)
|
|
|
+ else
|
|
|
+ Result := aGot = aExpected;
|
|
|
+end;
|
|
|
+
|
|
|
+var
|
|
|
+ ds: TDataSet;
|
|
|
+ v: Double;
|
|
|
+ hadexc: Boolean;
|
|
|
+ orgmask: TFPUExceptionMask;
|
|
|
+begin
|
|
|
+{$if defined(FPC_HAS_TYPE_EXTENDED) or not defined(FPC_HAS_TYPE_DOUBLE)}
|
|
|
+ { we rely on the floating point values to be doubles, so only test on systems
|
|
|
+ that use double as their largest type }
|
|
|
+ Exit;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ orgmask := GetExceptionMask;
|
|
|
+
|
|
|
+ Writeln('Testing with exceptions disabled');
|
|
|
+ SetExceptionMask(orgmask + [exPrecision, exInvalidOp]);
|
|
|
+ for ds in DataSet do begin
|
|
|
+ Writeln('Testing value ', ds.Value);
|
|
|
+ v := Frac(ds.Value);
|
|
|
+ if not SameValue(v, ds.AsIs) then begin
|
|
|
+ Writeln('Frac(', ds.Value, ') failed: expected ', ds.AsIs, ', but got ', v);
|
|
|
+ Halt(1);
|
|
|
+ end;
|
|
|
+ v := Frac(ds.Value + 0.5);
|
|
|
+ if not SameValue(v, ds.More) then begin
|
|
|
+ Writeln('Frac(', ds.Value, ' + 0.5) failed: expected ', ds.More, ', but got ', v);
|
|
|
+ Halt(2);
|
|
|
+ end;
|
|
|
+ v := Frac(ds.Value - 0.5);
|
|
|
+ if not SameValue(v, ds.Less) then begin
|
|
|
+ Writeln('Frac(', ds.Value, ' - 0.5) failed: expected ', ds.Less, ', but got ', v);
|
|
|
+ Halt(3);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ Writeln('Testing with exceptions enabled');
|
|
|
+ SetExceptionMask(orgmask);
|
|
|
+
|
|
|
+ for ds in DataSet do begin
|
|
|
+ hadexc := False;
|
|
|
+ try
|
|
|
+ Writeln('Testing value ', ds.Value);
|
|
|
+ v := Frac(ds.Value);
|
|
|
+ if not SameValue(v, ds.AsIs) then begin
|
|
|
+ Writeln('Frac(', ds.Value, ') failed: expected ', ds.AsIs, ', but got ', v);
|
|
|
+ Halt(1);
|
|
|
+ end;
|
|
|
+ v := Frac(ds.Value + 0.5);
|
|
|
+ if not SameValue(v, ds.More) then begin
|
|
|
+ Writeln('Frac(', ds.Value, ' + 0.5) failed: expected ', ds.More, ', but got ', v);
|
|
|
+ Halt(2);
|
|
|
+ end;
|
|
|
+ v := Frac(ds.Value - 0.5);
|
|
|
+ if not SameValue(v, ds.Less) then begin
|
|
|
+ Writeln('Frac(', ds.Value, ' - 0.5) failed: expected ', ds.Less, ', but got ', v);
|
|
|
+ Halt(3);
|
|
|
+ end;
|
|
|
+ except
|
|
|
+ on e: EMathError do begin
|
|
|
+ if ds.Exc then begin
|
|
|
+ Writeln('Got expected exception for value ', ds.Value);
|
|
|
+ hadexc := True;
|
|
|
+ end else
|
|
|
+ Writeln('Unexpected math exception for value ', ds.Value, ': ', e.Message);
|
|
|
+ end else
|
|
|
+ Writeln('Unexpected exception for value ', ds.Value, ': ', ExceptObject.ClassName);
|
|
|
+ end;
|
|
|
+ if ds.Exc and not hadexc then begin
|
|
|
+ Writeln('Exception expected, but none caught');
|
|
|
+ Halt(4);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ Writeln('ok');
|
|
|
+end.
|