Browse Source

* patch by Bart B to complete missing functions in the math unit, resolves #40055

florian 2 years ago
parent
commit
60c80a45a0
1 changed files with 248 additions and 4 deletions
  1. 248 4
      rtl/objpas/math.pp

+ 248 - 4
rtl/objpas/math.pp

@@ -406,8 +406,25 @@ function Csc(x : float) : float; inline;
 
 
 { inverse functions }
 { inverse functions }
 
 
-function ArcCos(x : float) : float;
-function ArcSin(x : float) : float;
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCos(x : Single) : Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCos(x : Double) : Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCos(x : Extended) : Extended;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcSin(x : Single) : Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcSin(x : Double) : Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcSin(x : Extended) : Extended;
+{$ENDIF}
 
 
 { calculates arctan(y/x) and returns an angle in the correct quadrant }
 { calculates arctan(y/x) and returns an angle in the correct quadrant }
 function ArcTan2(y,x : float) : float;
 function ArcTan2(y,x : float) : float;
@@ -458,6 +475,66 @@ function ArCosH(x : float) : float;
 function ArSinH(x : float) : float;
 function ArSinH(x : float) : float;
 function ArTanH(x : float) : float;
 function ArTanH(x : float) : float;
 
 
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcSec(X: Single): Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcSec(X: Double): Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcSec(X: Extended): Extended;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCsc(X: Single): Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCsc(X: Double): Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCsc(X: Extended): Extended;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCot(X: Single): Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCot(X: Double): Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCot(X: Extended): Extended;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcSecH(X : Single): Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcSecH(X : Double): Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcSecH(X : Extended): Extended;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCscH(X: Single): Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCscH(X: Double): Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCscH(X: Extended): Extended;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCotH(X: Single): Single;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCotH(X: Double): Double;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCotH(X: Extended): Extended;
+{$ENDIF}
+
 { triangle functions }
 { triangle functions }
 
 
 { returns the length of the hypotenuse of a right triangle }
 { returns the length of the hypotenuse of a right triangle }
@@ -1080,12 +1157,51 @@ begin
 end;
 end;
 
 
 { arcsin and arccos functions from AMath library (C) Copyright 2009-2013 Wolfgang Ehrhardt }
 { arcsin and arccos functions from AMath library (C) Copyright 2009-2013 Wolfgang Ehrhardt }
-function arcsin(x : float) : float;
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function arcsin(x : Single) : Single;
 begin
 begin
   arcsin:=arctan2(x,sqrt((1.0-x)*(1.0+x)));
   arcsin:=arctan2(x,sqrt((1.0-x)*(1.0+x)));
 end;
 end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function arcsin(x : Double) : Double;
+begin
+  arcsin:=arctan2(x,sqrt((1.0-x)*(1.0+x)));
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function arcsin(x : Extended) : Extended;
+begin
+  arcsin:=arctan2(x,sqrt((1.0-x)*(1.0+x)));
+end;
+{$ENDIF}
 
 
-function Arccos(x : Float) : Float;
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function Arccos(x : Single) : Single;
+begin
+  if abs(x)=1.0 then
+    if x<0.0 then
+      arccos:=Pi
+    else
+      arccos:=0
+  else
+    arccos:=arctan2(sqrt((1.0-x)*(1.0+x)),x);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function Arccos(x : Double) : Double;
+begin
+  if abs(x)=1.0 then
+    if x<0.0 then
+      arccos:=Pi
+    else
+      arccos:=0
+  else
+    arccos:=arctan2(sqrt((1.0-x)*(1.0+x)),x);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function Arccos(x : Extended) : Extended;
 begin
 begin
   if abs(x)=1.0 then
   if abs(x)=1.0 then
     if x<0.0 then
     if x<0.0 then
@@ -1095,6 +1211,7 @@ begin
   else
   else
     arccos:=arctan2(sqrt((1.0-x)*(1.0+x)),x);
     arccos:=arctan2(sqrt((1.0-x)*(1.0+x)),x);
 end;
 end;
+{$ENDIF}
 
 
 
 
 {$ifndef FPC_MATH_HAS_ARCTAN2}
 {$ifndef FPC_MATH_HAS_ARCTAN2}
@@ -1280,6 +1397,133 @@ function artanh(x : float) : float;
     artanh:=(lnxp1(x)-lnxp1(-x))*0.5;
     artanh:=(lnxp1(x)-lnxp1(-x))*0.5;
   end;
   end;
 
 
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcSec(X: Single): Single;
+begin
+  ArcSec:=ArcCos(1/X);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcSec(X: Double): Double;
+begin
+  ArcSec:=ArcCos(1/X);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcSec(X: Extended): Extended;
+begin
+  ArcSec:=ArcCos(1/X);
+end;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCsc(X: Single): Single;
+begin
+  ArcCsc:=ArcSin(1/X);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCsc(X: Double): Double;
+begin
+  ArcCsc:=ArcSin(1/X);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCsc(X: Extended): Extended;
+begin
+  ArcCsc:=ArcSin(1/X);
+end;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCot(X: Single): Single;
+begin
+  if x=0 then
+    ArcCot:=0.5*pi
+  else
+    ArcCot:=ArcTan(1/X);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCot(X: Double): Double;
+begin
+  begin
+    if x=0 then
+      ArcCot:=0.5*pi
+    else
+      ArcCot:=ArcTan(1/X);
+  end;
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCot(X: Extended): Extended;
+begin
+  begin
+    if x=0 then
+      ArcCot:=0.5*pi
+    else
+      ArcCot:=ArcTan(1/X);
+  end;
+end;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcSecH(X : Single): Single;
+begin
+  ArcSecH:=ln((1+(sqrt(1.0-sqr(X))))/X);  //replacing division inside ln() by subtracting 2 ln()'s seems to be slower
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcSecH(X : Double): Double;
+begin
+  ArcSecH:=ln((1+(sqrt(1.0-sqr(X))))/X);
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcSecH(X : Extended): Extended;
+begin
+  ArcSecH:=ln((1+(sqrt(1.0-sqr(X))))/X);
+end;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCscH(X: Single): Single;
+begin
+  ArcCscH:=ln((1.0/X)+sqrt(1.0/(sqr(x))+1.0));
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCscH(X: Double): Double;
+begin
+  ArcCscH:=ln((1.0/X)+sqrt(1.0/(sqr(x))+1.0));
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCscH(X: Extended): Extended;
+begin
+  ArcCscH:=ln((1.0/X)+sqrt(1.0/(sqr(x))+1.0));
+end;
+{$ENDIF}
+
+{$ifdef FPC_HAS_TYPE_SINGLE}
+function ArcCotH(X: Single): Single;
+begin
+  ArcCotH:=0.5*ln((x + 1.0)/(x - 1.0));
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_DOUBLE}
+function ArcCotH(X: Double): Double;
+begin
+  ArcCotH:=0.5*ln((x + 1.0)/(x - 1.0));
+end;
+{$ENDIF}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+function ArcCotH(X: Extended): Extended;
+begin
+  ArcCotH:=0.5*ln((x + 1.0)/(x - 1.0));
+end;
+{$ENDIF}
+
 { hypot function from AMath library (C) Copyright 2009-2013 Wolfgang Ehrhardt }
 { hypot function from AMath library (C) Copyright 2009-2013 Wolfgang Ehrhardt }
 function hypot(x,y : float) : float;
 function hypot(x,y : float) : float;
   begin
   begin