Implements math library

This commit is contained in:
Deukhoofd 2018-12-07 18:51:37 +01:00
parent f638c25483
commit e8369bb672
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
1 changed files with 224 additions and 0 deletions

View File

@ -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");
}
}
}