Browse Source

* handle frac(+/-Inf or Nan) correctly in the software implementation, resolves #39584

florian 3 years ago
parent
commit
67fedc6b5b
2 changed files with 35 additions and 4 deletions
  1. 11 4
      rtl/inc/genmath.inc
  2. 24 0
      tests/test/units/system/tfrac.pp

+ 11 - 4
rtl/inc/genmath.inc

@@ -1757,10 +1757,17 @@ end;
 
 
 
 
 {$ifndef FPC_SYSTEM_HAS_FRAC}
 {$ifndef FPC_SYSTEM_HAS_FRAC}
-    function fpc_frac_real(d : ValReal) : ValReal;compilerproc;
-    begin
-       result := d - Int(d);
-    end;
+function fpc_frac_real(d : ValReal) : ValReal;compilerproc;
+  var
+    i: integer;
+  begin
+    i := (float64high(d) and $7ff00000) shr 20;
+    if i=$7FF then
+      { return NaN }
+      result := (d-d)/0.0 
+    else
+      result := d - Int(d);
+  end;
 {$endif}
 {$endif}
 
 
 
 

+ 24 - 0
tests/test/units/system/tfrac.pp

@@ -0,0 +1,24 @@
+{ %OPT=-O- }
+uses
+  math,sysutils;
+var
+  d : double;  
+  s : string;    
+begin
+  SetExceptionMask([exInvalidOp]);
+  d:=Infinity;
+  str(frac(d),s);
+  writeln(s);
+  if pos('Nan',s)=0 then
+    halt(1);
+  d:=-Infinity;
+  str(frac(d),s);
+  writeln(s);
+  if pos('Nan',s)=0 then
+    halt(1);
+  d:=NaN;
+  str(frac(d),s);
+  writeln(s);
+  if pos('Nan',s)=0 then
+    halt(1);
+end.