Extended math RTL
This commit is contained in:
@@ -12,7 +12,17 @@ uses
|
||||
type
|
||||
TRtlMathFunctions = record
|
||||
public
|
||||
// --- Math Functions ---
|
||||
// --- Constants ---
|
||||
|
||||
[TRtlConst('Pi')]
|
||||
[AstDoc('Pi.')]
|
||||
class function CPi: Double; static;
|
||||
|
||||
[TRtlConst('e')]
|
||||
[AstDoc('Euler''s number.')]
|
||||
class function CE: Double; static;
|
||||
|
||||
// --- Basic Math ---
|
||||
|
||||
[TRtlExport('abs', Pure)]
|
||||
[AstDoc('Returns the absolute value of a number.')]
|
||||
@@ -44,6 +54,16 @@ type
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Sign(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('min', Pure)]
|
||||
[AstDoc('Returns the smaller of two numbers.')]
|
||||
[AstSignature('(number, number) -> number')]
|
||||
class function Min(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlExport('max', Pure)]
|
||||
[AstDoc('Returns the larger of two numbers.')]
|
||||
[AstSignature('(number, number) -> number')]
|
||||
class function Max(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlExport('sqrt', Pure)]
|
||||
[AstDoc('Returns the square root of a number.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
@@ -54,12 +74,98 @@ type
|
||||
[AstSignature('(number, number) -> number')]
|
||||
class function Pow(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlExport('exp', Pure)]
|
||||
[AstDoc('Returns e raised to the power of X.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Exp(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('log', Pure)]
|
||||
[AstDoc('Returns the natural logarithm (Base e).')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Log(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('log10', Pure)]
|
||||
[AstDoc('Returns the base-10 logarithm.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Log10(const Arg: TScalar): TScalar; static;
|
||||
|
||||
// --- Trigonometry ---
|
||||
|
||||
[TRtlExport('sin', Pure)]
|
||||
[AstDoc('Returns the sine of the angle (in radians).')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Sin(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('cos', Pure)]
|
||||
[AstDoc('Returns the cosine of the angle (in radians).')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Cos(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('tan', Pure)]
|
||||
[AstDoc('Returns the tangent of the angle (in radians).')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Tan(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('asin', Pure)]
|
||||
[AstDoc('Returns the arc sine.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function ArcSin(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('acos', Pure)]
|
||||
[AstDoc('Returns the arc cosine.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function ArcCos(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('atan', Pure)]
|
||||
[AstDoc('Returns the arc tangent.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function ArcTan(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('atan2', Pure)]
|
||||
[AstDoc('Returns the angle whose tangent is Y / X.')]
|
||||
[AstSignature('(y, x) -> number')]
|
||||
class function ArcTan2(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlExport('sinh', Pure)]
|
||||
[AstDoc('Returns the hyperbolic sine.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Sinh(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('cosh', Pure)]
|
||||
[AstDoc('Returns the hyperbolic cosine.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Cosh(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('tanh', Pure)]
|
||||
[AstDoc('Returns the hyperbolic tangent.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Tanh(const Arg: TScalar): TScalar; static;
|
||||
|
||||
// --- Conversion ---
|
||||
|
||||
[TRtlExport('deg2rad', Pure)]
|
||||
[AstDoc('Converts degrees to radians.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function DegToRad(const Arg: TScalar): TScalar; static;
|
||||
|
||||
[TRtlExport('rad2deg', Pure)]
|
||||
[AstDoc('Converts radians to degrees.')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function RadToDeg(const Arg: TScalar): TScalar; static;
|
||||
|
||||
// --- Utils ---
|
||||
|
||||
[TRtlExport('random', Impure)]
|
||||
[AstDoc('Returns a random number. No args: [0..1). Arg N: Integer [0..N).')]
|
||||
[AstSignature('() -> float')]
|
||||
[AstSignature('(number) -> number')]
|
||||
class function Random(const Args: TArray<TDataValue>): TDataValue; static;
|
||||
|
||||
[TRtlExport('is-NaN', Pure)]
|
||||
[AstDoc('Returns true if the value is Not-a-Number (NaN).')]
|
||||
[AstSignature('(number) -> boolean')]
|
||||
class function IsNaN(const Arg: TScalar): TScalar; static;
|
||||
|
||||
// --- Static Specializations ---
|
||||
|
||||
[TRtlExport('abs', Pure)]
|
||||
@@ -91,16 +197,57 @@ type
|
||||
[TRtlExport('pow', Pure)]
|
||||
class function Pow_Float_Ordinal_Float(A: Double; B: Int64): Double; static;
|
||||
|
||||
[TRtlExport('min', Pure)]
|
||||
class function Min_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static;
|
||||
[TRtlExport('min', Pure)]
|
||||
class function Min_Float_Float_Float(A, B: Double): Double; static;
|
||||
|
||||
[TRtlExport('max', Pure)]
|
||||
class function Max_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64; static;
|
||||
[TRtlExport('max', Pure)]
|
||||
class function Max_Float_Float_Float(A, B: Double): Double; static;
|
||||
|
||||
[TRtlExport('exp', Pure)]
|
||||
class function Exp_Float_Float(A: Double): Double; static;
|
||||
[TRtlExport('log', Pure)]
|
||||
class function Log_Float_Float(A: Double): Double; static;
|
||||
[TRtlExport('log10', Pure)]
|
||||
class function Log10_Float_Float(A: Double): Double; static;
|
||||
|
||||
[TRtlExport('sin', Pure)]
|
||||
class function Sin_Float_Float(A: Double): Double; static;
|
||||
[TRtlExport('cos', Pure)]
|
||||
class function Cos_Float_Float(A: Double): Double; static;
|
||||
[TRtlExport('tan', Pure)]
|
||||
class function Tan_Float_Float(A: Double): Double; static;
|
||||
|
||||
[TRtlExport('random', Impure)]
|
||||
class function Random_Void_Float: Double; static;
|
||||
[TRtlExport('random', Impure)]
|
||||
class function Random_Ordinal_Ordinal(Limit: Int64): Int64; static;
|
||||
|
||||
[TRtlExport('is-NaN', Pure)]
|
||||
class function IsNaN_Float_Ordinal(A: Double): Int64; static;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TRtlMathFunctions }
|
||||
|
||||
// --- Constants ---
|
||||
|
||||
class function TRtlMathFunctions.CPi: Double;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Pi);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.CE: Double;
|
||||
begin
|
||||
Result := TScalar.FromDouble(2.71828182845904523536);
|
||||
end;
|
||||
|
||||
// --- Basic Math ---
|
||||
|
||||
class function TRtlMathFunctions.Abs(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
case Arg.Kind of
|
||||
@@ -169,6 +316,34 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Min(const Args: TArray<TDataValue>): TDataValue;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Min requires 2 arguments.');
|
||||
|
||||
var a: TScalar := Args[0].AsScalar;
|
||||
var b: TScalar := Args[1].AsScalar;
|
||||
|
||||
if (a.Kind = TScalar.TKind.Ordinal) and (b.Kind = TScalar.TKind.Ordinal) then
|
||||
Result := TScalar.FromInt64(System.Math.Min(a.Value.AsInt64, b.Value.AsInt64))
|
||||
else
|
||||
Result := TScalar.FromDouble(System.Math.Min(Double(a), Double(b)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Max(const Args: TArray<TDataValue>): TDataValue;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Max requires 2 arguments.');
|
||||
|
||||
var a: TScalar := Args[0].AsScalar;
|
||||
var b: TScalar := Args[1].AsScalar;
|
||||
|
||||
if (a.Kind = TScalar.TKind.Ordinal) and (b.Kind = TScalar.TKind.Ordinal) then
|
||||
Result := TScalar.FromInt64(System.Math.Max(a.Value.AsInt64, b.Value.AsInt64))
|
||||
else
|
||||
Result := TScalar.FromDouble(System.Math.Max(Double(a), Double(b)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sqrt(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
var val: Double := Arg; // Implicit cast handles Ordinal and Float
|
||||
@@ -185,6 +360,92 @@ begin
|
||||
Result := TScalar.FromDouble(System.Math.Power(baseVal, expVal));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Exp(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Exp(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Log(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Ln(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Log10(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.Log10(Double(Arg)));
|
||||
end;
|
||||
|
||||
// --- Trigonometry ---
|
||||
|
||||
class function TRtlMathFunctions.Sin(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Sin(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Cos(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Cos(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Tan(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.Tan(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.ArcSin(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.ArcSin(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.ArcCos(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.ArcCos(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.ArcTan(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.ArcTan(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.ArcTan2(const Args: TArray<TDataValue>): TDataValue;
|
||||
begin
|
||||
if Length(Args) <> 2 then
|
||||
raise EArgumentException.Create('Atan2 requires 2 arguments (Y, X).');
|
||||
|
||||
var y: Double := Args[0].AsScalar;
|
||||
var x: Double := Args[1].AsScalar;
|
||||
Result := TScalar.FromDouble(System.Math.ArcTan2(y, x));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sinh(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.Sinh(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Cosh(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.Cosh(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Tanh(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.Tanh(Double(Arg)));
|
||||
end;
|
||||
|
||||
// --- Conversion ---
|
||||
|
||||
class function TRtlMathFunctions.DegToRad(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.DegToRad(Double(Arg)));
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.RadToDeg(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
Result := TScalar.FromDouble(System.Math.RadToDeg(Double(Arg)));
|
||||
end;
|
||||
|
||||
// --- Utils ---
|
||||
|
||||
class function TRtlMathFunctions.Random(const Args: TArray<TDataValue>): TDataValue;
|
||||
begin
|
||||
if Length(Args) = 0 then
|
||||
@@ -195,6 +456,14 @@ begin
|
||||
raise EArgumentException.Create('Random expects 0 arguments or 1 integer argument.');
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.IsNaN(const Arg: TScalar): TScalar;
|
||||
begin
|
||||
if (Arg.Kind = TScalar.TKind.Float) and Arg.Value.AsDouble.IsNaN then
|
||||
Result := TScalar.FromBoolean(True)
|
||||
else
|
||||
Result := TScalar.FromBoolean(False);
|
||||
end;
|
||||
|
||||
// --- Static Specializations ---
|
||||
|
||||
class function TRtlMathFunctions.Abs_Ordinal_Ordinal(A: Int64): Int64;
|
||||
@@ -257,6 +526,56 @@ begin
|
||||
Result := System.Math.Power(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Min_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
|
||||
begin
|
||||
Result := System.Math.Min(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Min_Float_Float_Float(A, B: Double): Double;
|
||||
begin
|
||||
Result := System.Math.Min(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Max_Ordinal_Ordinal_Ordinal(A, B: Int64): Int64;
|
||||
begin
|
||||
Result := System.Math.Max(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Max_Float_Float_Float(A, B: Double): Double;
|
||||
begin
|
||||
Result := System.Math.Max(A, B);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Exp_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Exp(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Log_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Ln(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Log10_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Math.Log10(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Sin_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Sin(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Cos_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Cos(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Tan_Float_Float(A: Double): Double;
|
||||
begin
|
||||
Result := System.Math.Tan(A);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.Random_Void_Float: Double;
|
||||
begin
|
||||
Result := System.Random;
|
||||
@@ -267,4 +586,9 @@ begin
|
||||
Result := System.Random(Limit);
|
||||
end;
|
||||
|
||||
class function TRtlMathFunctions.IsNaN_Float_Ordinal(A: Double): Int64;
|
||||
begin
|
||||
Result := Ord(A.IsNaN);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user