Преглед на файлове

* overloaded versions of IsNan, resolves #14351
* prefer <ord> -> single over <ord> -> double/extended, this is delphi compatible

git-svn-id: trunk@17758 -

florian преди 14 години
родител
ревизия
37b8b791d5
променени са 2 файла, в които са добавени 58 реда и са изтрити 1 реда
  1. 6 1
      compiler/defcmp.pas
  2. 52 0
      rtl/objpas/math.pp

+ 6 - 1
compiler/defcmp.pas

@@ -536,7 +536,12 @@ implementation
                           (s64currencytype.typ = floatdef))) then
                        begin
                          doconv:=tc_int_2_real;
-                         eq:=te_convert_l4;
+
+                         { prefer single over others }
+                         if is_single(def_to) then
+                           eq:=te_convert_l3
+                         else
+                           eq:=te_convert_l4;
                        end
                      else if is_currency(def_from)
                              { and (s64currencytype.typ = orddef)) } then

+ 52 - 0
rtl/objpas/math.pp

@@ -204,7 +204,13 @@ function IsZero(const A: Extended; Epsilon: Extended): Boolean; overload;
 function IsZero(const A: Extended): Boolean;inline; overload;
 {$endif FPC_HAS_TYPE_EXTENDED}
 
+function IsNan(const d : Single): Boolean; overload;
+{$ifdef FPC_HAS_TYPE_DOUBLE}
 function IsNan(const d : Double): Boolean; overload;
+{$endif FPC_HAS_TYPE_DOUBLE}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function IsNan(const d : Extended): Boolean; overload;
+{$endif FPC_HAS_TYPE_EXTENDED}
 function IsInfinite(const d : Double): Boolean;
 
 {$ifdef FPC_HAS_TYPE_EXTENDED}
@@ -2133,6 +2139,29 @@ type
     cards: Array[0..1] of cardinal;
   end;
 
+
+function IsNan(const d : Single): Boolean; overload;
+  type
+    TSplitSingle = packed record
+      case byte of
+        0: (bytes: Array[0..3] of byte);
+        1: (words: Array[0..1] of word);
+        2: (cards: Array[0..0] of cardinal);
+    end;
+  var
+    fraczero, expMaximal: boolean;
+  begin
+{$ifdef FPC_BIG_ENDIAN}
+    expMaximal := ((TSplitSingle(d).words[0] shr 7) and $ff) = 255;
+    fraczero:= (TSplitSingle(d).cards[0] and $7fffff = 0);
+{$else FPC_BIG_ENDIAN}
+    expMaximal := ((TSplitSingle(d).words[1] shr 7) and $ff) = 255;
+    fraczero := (TSplitSingle(d).cards[0] and $7fffff = 0);
+{$endif FPC_BIG_ENDIAN}
+    Result:=expMaximal and not(fraczero);
+  end;
+
+{$ifdef FPC_HAS_TYPE_DOUBLE}
 function IsNan(const d : Double): Boolean;
   var
     fraczero, expMaximal: boolean;
@@ -2148,7 +2177,30 @@ function IsNan(const d : Double): Boolean;
 {$endif FPC_BIG_ENDIAN}
     Result:=expMaximal and not(fraczero);
   end;
+{$endif FPC_HAS_TYPE_DOUBLE}
 
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function IsNan(const d : Extended): Boolean; overload;
+  type
+    TSplitExtended = packed record
+      case byte of
+        0: (bytes: Array[0..9] of byte);
+        1: (words: Array[0..4] of word);
+        2: (cards: Array[0..1] of cardinal; w: word);
+    end;
+  var
+    fraczero, expMaximal: boolean;
+  begin
+{$ifdef FPC_BIG_ENDIAN}
+  {$error no support for big endian extended type yet}
+{$else FPC_BIG_ENDIAN}
+    expMaximal := (TSplitExtended(d).w and $7fff) = 32767;
+    fraczero := (TSplitExtended(d).cards[0] = 0) and
+                    ((TSplitExtended(d).cards[1] and $7fffffff) = 0);
+{$endif FPC_BIG_ENDIAN}
+    Result:=expMaximal and not(fraczero);
+  end;
+{$endif FPC_HAS_TYPE_EXTENDED}
 
 function IsInfinite(const d : Double): Boolean;
   var