Implements math library
This commit is contained in:
parent
f638c25483
commit
e8369bb672
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Upsilon.BaseTypes;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
|
||||
namespace Upsilon.StandardLibraries
|
||||
|
@ -14,5 +16,227 @@ namespace Upsilon.StandardLibraries
|
|||
}
|
||||
return new ScriptNumberLong(Math.Abs(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("acos", "Returns the arc cosine of x (in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber ArcCosine(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Acos(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Acos(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("asin", "Returns the arc sine of x (in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber ArcSine(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Asin(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Asin(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("atan", "Returns the arc tangent of y (in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber ArcTangent(ScriptNumber a, ScriptNumber b = null)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Atan(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Atan(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("atan", "Returns the arc tangent of y/x (in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber ArcTangent2(ScriptNumber a, ScriptNumber b)
|
||||
{
|
||||
if (a.IsFloat && b.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(
|
||||
Math.Atan2(((ScriptNumberDouble) a).Value, ((ScriptNumberDouble) b).Value));
|
||||
}
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(
|
||||
Math.Atan2(((ScriptNumberDouble) a).Value, ((ScriptNumberLong) b).Value));
|
||||
}
|
||||
if (b.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(
|
||||
Math.Atan2(((ScriptNumberLong) a).Value, ((ScriptNumberDouble) b).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(
|
||||
Math.Atan2(((ScriptNumberLong) a).Value, ((ScriptNumberLong) b).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("ceil", "Returns the smallest integral value larger than or equal to x.", directScriptManipulation: true)]
|
||||
public ScriptNumber Ceiling(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberLong((long) Math.Ceiling(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
[ScriptFunction("cos", "Returns the cosine of x (assumed to be in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber Cosine(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Cos(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Cos(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("deg", "Converts the angle x from radians to degrees.", directScriptManipulation: true)]
|
||||
public ScriptNumber Degrees(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble((180 / Math.PI) * ((ScriptNumberDouble)a).Value);
|
||||
}
|
||||
return new ScriptNumberDouble((180 / Math.PI) * ((ScriptNumberLong)a).Value);
|
||||
}
|
||||
|
||||
[ScriptFunction("exp", "Returns the value e^x (where e is the base of natural logarithms).", directScriptManipulation: true)]
|
||||
public ScriptNumber Exponent(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Exp(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Exp(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("floor", "Returns the largest integral value smaller than or equal to x.", directScriptManipulation: true)]
|
||||
public ScriptNumber Floor(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberLong((long) Math.Floor(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
[ScriptFunction("fmod", "Returns the remainder of the division of x by y that rounds the quotient towards zero. (integer/float)",
|
||||
directScriptManipulation: true)]
|
||||
public ScriptNumber FModulo(ScriptNumber a, ScriptNumber b)
|
||||
{
|
||||
return a % b;
|
||||
}
|
||||
|
||||
public ScriptNumberDouble Huge { get; } = new ScriptNumberDouble(double.MaxValue);
|
||||
|
||||
[ScriptFunction("log", "Returns the logarithm of x in the given base. The default for base is e (so that the function returns the natural logarithm of x).", directScriptManipulation: true)]
|
||||
public ScriptNumber Logarithm(ScriptNumber a, ScriptNumber b = null)
|
||||
{
|
||||
var @base = Math.E;
|
||||
if (b != null)
|
||||
{
|
||||
@base = (double) b.ToCSharpObject();
|
||||
}
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Log(((ScriptNumberDouble) a).Value, @base));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Log(((ScriptNumberLong) a).Value, @base));
|
||||
}
|
||||
|
||||
public ScriptNumberLong MaxInteger { get; } = new ScriptNumberLong(long.MaxValue);
|
||||
public ScriptNumberLong MinInteger { get; } = new ScriptNumberLong(long.MinValue);
|
||||
|
||||
[ScriptFunction("modf", "Returns the integral part of x and the fractional part of x. Its second result is always a float.",
|
||||
directScriptManipulation: true)]
|
||||
public SimpleScriptTable ModuloIntegral(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
var integral = new ScriptNumberLong((long) ((ScriptNumberDouble)a).Value);
|
||||
var remainder = new ScriptNumberDouble(((ScriptNumberDouble) a).Value % 1);
|
||||
return new SimpleScriptTable(new List<ScriptType>(){integral, remainder});
|
||||
}
|
||||
|
||||
return new SimpleScriptTable(new List<ScriptType>()
|
||||
{new ScriptNumberLong((long) a.ToCSharpObject()), new ScriptNumberDouble(0)});
|
||||
}
|
||||
|
||||
public ScriptNumberDouble Pi { get; } = new ScriptNumberDouble(Math.PI);
|
||||
|
||||
[ScriptFunction("rad", "Converts the angle x from degrees to radians.", directScriptManipulation: true)]
|
||||
public ScriptNumber Radians(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble((Math.PI / 180) * ((ScriptNumberDouble) a).Value);
|
||||
}
|
||||
return new ScriptNumberDouble((Math.PI / 180) * ((ScriptNumberLong)a).Value);
|
||||
}
|
||||
|
||||
private static Random _rand = new Random();
|
||||
[ScriptFunction("random", "When called without arguments, returns a pseudo-random float with uniform distribution in the range [0,1). When called with two integers m and n, math.random returns a pseudo-random integer with uniform distribution in the range [m, n]. (The value n-m cannot be negative and must fit in a Lua integer.) The call math.random(n) is equivalent to math.random(1,n).", directScriptManipulation: true)]
|
||||
public ScriptNumber Random(ScriptNumber a = null,ScriptNumber b = null)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
return new ScriptNumberDouble(_rand.NextDouble());
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
{
|
||||
var max = Convert.ToInt32(a.ToCSharpObject());
|
||||
return new ScriptNumberLong(_rand.Next(max));
|
||||
}
|
||||
else
|
||||
{
|
||||
var min = Convert.ToInt32(a.ToCSharpObject());
|
||||
var max = Convert.ToInt32(b.ToCSharpObject());
|
||||
return new ScriptNumberLong(_rand.Next(min, max));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[ScriptFunction("randomseed", "Sets x as the \"seed\" for the pseudo-random generator: equal seeds produce equal sequences of numbers.", directScriptManipulation: true)]
|
||||
public void RandomSeed(ScriptNumber a)
|
||||
{
|
||||
var v = a.ToCSharpObject().GetHashCode();
|
||||
_rand = new Random(v);
|
||||
}
|
||||
|
||||
[ScriptFunction("sin", "Returns the sine of x (assumed to be in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber Sine(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Sin(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Sin(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("sqrt", "Returns the square root of x. (You can also use the expression x^0.5 to compute this value.)", directScriptManipulation: true)]
|
||||
public ScriptNumber SquareRoot(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Sqrt(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Sqrt(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("tan", "Returns the tangent of x (assumed to be in radians).", directScriptManipulation: true)]
|
||||
public ScriptNumber Tangens(ScriptNumber a)
|
||||
{
|
||||
if (a.IsFloat)
|
||||
{
|
||||
return new ScriptNumberDouble(Math.Tan(((ScriptNumberDouble) a).Value));
|
||||
}
|
||||
return new ScriptNumberDouble(Math.Tan(((ScriptNumberLong) a).Value));
|
||||
}
|
||||
|
||||
[ScriptFunction("type", "Returns \"integer\" if x is an integer, \"float\" if it is a float.", directScriptManipulation: true)]
|
||||
public ScriptString Type(ScriptNumber a)
|
||||
{
|
||||
return a.IsFloat ? new ScriptString("float") : new ScriptString("integer");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue