99 lines
3.7 KiB
C#
99 lines
3.7 KiB
C#
namespace Upsilon.BaseTypes.Number
|
|
{
|
|
internal abstract class Number : LuaType
|
|
{
|
|
protected abstract bool IsFloat { get; }
|
|
|
|
public override Type Type => Type.Number;
|
|
|
|
#region Binary Operators
|
|
|
|
public static Number operator + (Number a, Number b)
|
|
{
|
|
if (!a.IsFloat && !b.IsFloat)
|
|
return new NumberLong(((NumberLong) a).Value + ((NumberLong) b).Value);
|
|
if (a.IsFloat && b.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value + ((NumberDouble) b).Value);
|
|
if (a.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value + ((NumberLong) b).Value);
|
|
return new NumberDouble(((NumberLong) a).Value + ((NumberDouble) b).Value);
|
|
}
|
|
|
|
public static Number operator - (Number a, Number b)
|
|
{
|
|
if (!a.IsFloat && !b.IsFloat)
|
|
return new NumberLong(((NumberLong) a).Value - ((NumberLong) b).Value);
|
|
if (a.IsFloat && b.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value - ((NumberDouble) b).Value);
|
|
if (a.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value - ((NumberLong) b).Value);
|
|
return new NumberDouble(((NumberLong) a).Value - ((NumberDouble) b).Value);
|
|
}
|
|
|
|
public static Number operator * (Number a, Number b)
|
|
{
|
|
if (!a.IsFloat && !b.IsFloat)
|
|
return new NumberLong(((NumberLong) a).Value * ((NumberLong) b).Value);
|
|
if (a.IsFloat && b.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value * ((NumberDouble) b).Value);
|
|
if (a.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value * ((NumberLong) b).Value);
|
|
return new NumberDouble(((NumberLong) a).Value * ((NumberDouble) b).Value);
|
|
}
|
|
|
|
public static Number operator / (Number a, Number b)
|
|
{
|
|
if (!a.IsFloat && !b.IsFloat)
|
|
return new NumberLong(((NumberLong) a).Value / ((NumberLong) b).Value);
|
|
if (a.IsFloat && b.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value / ((NumberDouble) b).Value);
|
|
if (a.IsFloat)
|
|
return new NumberDouble(((NumberDouble) a).Value / ((NumberLong) b).Value);
|
|
return new NumberDouble(((NumberLong) a).Value / ((NumberDouble) b).Value);
|
|
}
|
|
#endregion
|
|
|
|
public static Number operator - (Number n)
|
|
{
|
|
if (n.IsFloat)
|
|
return new NumberDouble(-((NumberDouble)n).Value);
|
|
return new NumberLong(-((NumberLong)n).Value);
|
|
}
|
|
|
|
#region Equality
|
|
private bool Equals(Number other)
|
|
{
|
|
if (!IsFloat && !other.IsFloat)
|
|
return ((NumberLong) this).Value.Equals(((NumberLong) other).Value);
|
|
if (IsFloat && other.IsFloat)
|
|
return ((NumberDouble) this).Value.Equals(((NumberDouble) other).Value);
|
|
return false;
|
|
}
|
|
|
|
#pragma warning disable 659
|
|
public override bool Equals(object obj)
|
|
#pragma warning restore 659
|
|
{
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
if (ReferenceEquals(this, obj)) return true;
|
|
if (obj.GetType() != this.GetType()) return false;
|
|
return Equals((Number) obj);
|
|
}
|
|
|
|
#endregion
|
|
|
|
public static explicit operator double(Number n)
|
|
{
|
|
if (n.IsFloat)
|
|
return ((NumberDouble) n);
|
|
return ((NumberLong) n).Value;
|
|
}
|
|
|
|
public static explicit operator long(Number n)
|
|
{
|
|
if (n.IsFloat)
|
|
return (long)((NumberDouble) n).Value;
|
|
return ((NumberLong) n).Value;
|
|
}
|
|
}
|
|
} |