2
0

tb0643.pp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. { %OPT=-CE }
  2. { this test is geared towards Double values }
  3. program tb0643;
  4. {$mode objfpc}
  5. uses
  6. Math, sysutils;
  7. type
  8. TDataset = record
  9. Value: Double;
  10. AsIs: Double;
  11. More: Double;
  12. Less: Double;
  13. Exc: Boolean;
  14. end;
  15. var
  16. DataSet: array[0..15] of TDataset = (
  17. (Value: 1.5; AsIs: 0.5; More: 0; Less: 0; Exc: False),
  18. (Value: 0; AsIs: 0; More: 0.5; Less: -0.5; Exc: False),
  19. (Value: 2251799813685248; AsIs: 0; More: 0.5; Less: 0.5; Exc: False),
  20. (Value: 4503599627370496; AsIs: 0; More: 0; Less: 0.5; Exc: False),
  21. (Value: 1E300; AsIs: 0; More: 0; Less: 0; Exc: False),
  22. (Value: 0.125; AsIs: 0.125; More: 0.625; Less: -0.375; Exc: False),
  23. (Value: 3.6415926535897932384626433832795; AsIs: 0.64159265358979312; More: 0.14159265358979312; Less: 0.14159265358979312; Exc: False),
  24. (Value: -1.5; AsIs: -0.5; More: 0; Less: 0; Exc: False),
  25. (Value: -2251799813685248; AsIs: 0; More: -0.5; Less: -0.5; Exc: False),
  26. (Value: -4503599627370496; AsIs: 0; More: -0.5; Less: 0; Exc: False),
  27. (Value: -1E300; AsIs: 0; More: 0; Less: 0; Exc: False),
  28. (Value: -0.125; AsIs: -0.125; More: 0.375; Less: -0.625; Exc: False),
  29. (Value: -3.6415926535897932384626433832795; AsIs: -0.64159265358979312; More: -0.14159265358979312; Less: -0.14159265358979312; Exc: False),
  30. (Value: Infinity; AsIs: NaN; More: NaN; Less: NaN; Exc: True),
  31. (Value: NegInfinity; AsIs: NaN; More: NaN; Less: NaN; Exc: True),
  32. (Value: NaN; AsIs: NaN; More: NaN; Less: NaN; Exc: False)
  33. );
  34. function SameValue(aGot, aExpected: Double): Boolean;
  35. begin
  36. if IsNan(aExpected) then
  37. Result := IsNan(aGot)
  38. else
  39. Result := aGot = aExpected;
  40. end;
  41. var
  42. ds: TDataSet;
  43. v: Double;
  44. hadexc: Boolean;
  45. orgmask: TFPUExceptionMask;
  46. begin
  47. {$if defined(FPC_HAS_TYPE_EXTENDED) or not defined(FPC_HAS_TYPE_DOUBLE)}
  48. { we rely on the floating point values to be doubles, so only test on systems
  49. that use double as their largest type }
  50. Exit;
  51. {$endif}
  52. orgmask := GetExceptionMask;
  53. Writeln('Testing with exceptions disabled');
  54. SetExceptionMask(orgmask + [exPrecision, exInvalidOp]);
  55. for ds in DataSet do begin
  56. Writeln('Testing value ', ds.Value);
  57. v := Frac(ds.Value);
  58. if not SameValue(v, ds.AsIs) then begin
  59. Writeln('Frac(', ds.Value, ') failed: expected ', ds.AsIs, ', but got ', v);
  60. Halt(1);
  61. end;
  62. v := Frac(ds.Value + 0.5);
  63. if not SameValue(v, ds.More) then begin
  64. Writeln('Frac(', ds.Value, ' + 0.5) failed: expected ', ds.More, ', but got ', v);
  65. Halt(2);
  66. end;
  67. v := Frac(ds.Value - 0.5);
  68. if not SameValue(v, ds.Less) then begin
  69. Writeln('Frac(', ds.Value, ' - 0.5) failed: expected ', ds.Less, ', but got ', v);
  70. Halt(3);
  71. end;
  72. end;
  73. Writeln('Testing with exceptions enabled');
  74. SetExceptionMask(orgmask);
  75. for ds in DataSet do begin
  76. hadexc := False;
  77. try
  78. Writeln('Testing value ', ds.Value);
  79. v := Frac(ds.Value);
  80. if not SameValue(v, ds.AsIs) then begin
  81. Writeln('Frac(', ds.Value, ') failed: expected ', ds.AsIs, ', but got ', v);
  82. Halt(1);
  83. end;
  84. v := Frac(ds.Value + 0.5);
  85. if not SameValue(v, ds.More) then begin
  86. Writeln('Frac(', ds.Value, ' + 0.5) failed: expected ', ds.More, ', but got ', v);
  87. Halt(2);
  88. end;
  89. v := Frac(ds.Value - 0.5);
  90. if not SameValue(v, ds.Less) then begin
  91. Writeln('Frac(', ds.Value, ' - 0.5) failed: expected ', ds.Less, ', but got ', v);
  92. Halt(3);
  93. end;
  94. except
  95. on e: EMathError do begin
  96. if ds.Exc then begin
  97. Writeln('Got expected exception for value ', ds.Value);
  98. hadexc := True;
  99. end else
  100. Writeln('Unexpected math exception for value ', ds.Value, ': ', e.Message);
  101. end else
  102. Writeln('Unexpected exception for value ', ds.Value, ': ', ExceptObject.ClassName);
  103. end;
  104. if ds.Exc and not hadexc then begin
  105. Writeln('Exception expected, but none caught');
  106. Halt(4);
  107. end;
  108. end;
  109. Writeln('ok');
  110. end.