750 lines
23 KiB
C#
750 lines
23 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Numerics;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
using Newtonsoft.Json.Linq;
|
|
using Amazon.DynamoDBv2.Model;
|
|
|
|
|
|
namespace ServerCore;
|
|
|
|
// HANDOVER: 수학적 처리 함수를 제공 한다. (float, double, decimal 자료형 제공)
|
|
|
|
public static class MathHelper
|
|
{
|
|
// The infamous ''3.14159265358979...'' value (RO).
|
|
public const float PI = (float)Math.PI;
|
|
|
|
// A representation of positive infinity (RO).
|
|
public const float Infinity = Single.PositiveInfinity;
|
|
|
|
// A representation of negative infinity (RO).
|
|
public const float NegativeInfinity = Single.NegativeInfinity;
|
|
|
|
// Degrees-to-radians conversion constant (RO).
|
|
public const float Deg2Rad = PI * 2F / 360F;
|
|
|
|
// Radians-to-degrees conversion constant (RO).
|
|
public const float Rad2Deg = 1F / Deg2Rad;
|
|
|
|
|
|
|
|
// Returns the sine of angle /value/ in radians.
|
|
public static T sin<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)MathF.Sin(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)Math.Sin(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)(decimal)Math.Sin(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the cosine of angle /value/ in radians.
|
|
public static T cos<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)MathF.Cos(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)Math.Cos(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)(decimal)Math.Sin(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the tangent of angle /value/ in radians.
|
|
public static T tan<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)MathF.Tan(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)Math.Tan(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)(decimal)Math.Tan(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the arc-sine of /value/ - the angle in radians whose sine is /f/.
|
|
public static T asin<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)MathF.Asin(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)Math.Asin(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)(decimal)Math.Asin(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the arc-cosine of /value/ - the angle in radians whose cosine is /f/.
|
|
public static T acos<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)MathF.Acos(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)Math.Acos(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)(decimal)Math.Acos(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the arc-tangent of /value/ - the angle in radians whose tangent is /f/.
|
|
public static T atan<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)MathF.Atan(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)Math.Atan(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)Math.Atan(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the angle in radians whose ::ref::Tan is @@y/x@@.
|
|
public static T atan2<T>(T y, T x)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result_y = Convert.ToSingle(y);
|
|
var result_x = Convert.ToSingle(x);
|
|
return (T)(object)MathF.Atan2(result_y, result_x);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result_y = Convert.ToDouble(y);
|
|
var result_x = Convert.ToDouble(x);
|
|
return (T)(object)Math.Atan2(result_y, result_x);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result_y = Convert.ToDecimal(y);
|
|
var round_result_y = Math.Round((double)result_y, 28);
|
|
var result_x = Convert.ToDecimal(x);
|
|
var round_result_x = Math.Round((double)result_x, 28);
|
|
return (T)(object)(decimal)Math.Atan2(round_result_y, round_result_x);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : y:{y}, x:{x}");
|
|
}
|
|
}
|
|
|
|
// Returns square root of /value/.
|
|
public static T sqrt<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Sqrt(Convert.ToSingle(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Sqrt(Convert.ToDouble(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
var round_result = Math.Round((double)result, 28);
|
|
return (T)(object)(decimal)Math.Sqrt(round_result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the absolute value of /value/.
|
|
public static T abs<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(Int16))
|
|
{
|
|
var result = (Int16)Math.Abs(Convert.ToInt16(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(Int32))
|
|
{
|
|
var result = (Int32)Math.Abs(Convert.ToInt32(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Abs(Convert.ToSingle(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Abs(Convert.ToDouble(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Math.Abs(Convert.ToDecimal(value));
|
|
return (T)(object)result;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// *listonly*
|
|
public static T min<T>(T a, T b)
|
|
where T : struct, IComparable<T>
|
|
{
|
|
return a.CompareTo(b) < 0 ? a : b;
|
|
}
|
|
|
|
// Returns the smallest of two or more values.
|
|
public static T min<T>(params T[] values)
|
|
where T : struct, IComparable<T>
|
|
{
|
|
int len = values.Length;
|
|
if (len == 0)
|
|
{
|
|
return default(T);
|
|
}
|
|
|
|
T min_value = values[0];
|
|
for (int i = 1; i < len; i++)
|
|
{
|
|
if (values[i].CompareTo(min_value) < 0)
|
|
min_value = values[i];
|
|
}
|
|
|
|
return min_value;
|
|
}
|
|
public static T max<T>(T a, T b)
|
|
where T : IComparable<T>
|
|
{
|
|
return a.CompareTo(b) > 0 ? a : b;
|
|
}
|
|
|
|
public static T max<T>(params T[] values)
|
|
where T : IComparable<T>
|
|
{
|
|
if (values.Length == 0)
|
|
{
|
|
throw new ArgumentException("At least one value must be provided.", nameof(values));
|
|
}
|
|
|
|
T max_value = values[0];
|
|
for (int i = 1; i < values.Length; i++)
|
|
{
|
|
if (values[i].CompareTo(max_value) > 0)
|
|
{
|
|
max_value = values[i];
|
|
}
|
|
}
|
|
|
|
return max_value;
|
|
}
|
|
|
|
// Returns /f/ raised to power /p/.
|
|
public static T pow<T>(T baseValue, T exponent)
|
|
where T : struct, IConvertible
|
|
{
|
|
// 타입에 따라 적절한 연산을 수행
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var base_v = Convert.ToSingle(baseValue);
|
|
var exponent_v = Convert.ToSingle(exponent);
|
|
return (T)(object)MathF.Pow(base_v, exponent_v);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var base_v = Convert.ToDouble(baseValue);
|
|
var exponent_v = Convert.ToDouble(exponent);
|
|
return (T)(object)(double)Math.Pow(base_v, exponent_v);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var base_v = Convert.ToDecimal(baseValue);
|
|
var exponent_v = Convert.ToDecimal(exponent);
|
|
var round_result_base_v = Math.Round((double)base_v, 28);
|
|
var round_result_exponent_v = Math.Round((double)exponent_v, 28);
|
|
return (T)(object)(decimal)Math.Pow(round_result_base_v, round_result_exponent_v);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {baseValue}, {exponent}");
|
|
}
|
|
}
|
|
|
|
|
|
// Returns e raised to the specified power.
|
|
public static T exp<T>(T power)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var power_v = Convert.ToSingle(power);
|
|
return (T)(object)MathF.Exp(power_v);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var power_v = Convert.ToDouble(power);
|
|
return (T)(object)(double)Math.Exp(power_v);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var power_v = Convert.ToDecimal(power);
|
|
var round_result_power_v = Math.Round((double)power_v, 28);
|
|
return (T)(object)(decimal)Math.Exp(round_result_power_v);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {power}");
|
|
}
|
|
}
|
|
|
|
// Returns the logarithm of a specified number in a specified base.
|
|
public static T log<T>(T f, T p)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var base_v = Convert.ToSingle(f);
|
|
var power_v = Convert.ToSingle(p);
|
|
return (T)(object)MathF.Log(base_v, power_v);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var base_v = Convert.ToDouble(f);
|
|
var power_v = Convert.ToDouble(p);
|
|
return (T)(object)(double)Math.Log(base_v, power_v);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var base_v = Convert.ToDecimal(f);
|
|
var power_v = Convert.ToDecimal(p);
|
|
var round_result_base_v = Math.Round((double)base_v, 28);
|
|
var round_result_power_v = Math.Round((double)power_v, 28);
|
|
return (T)(object)(decimal)Math.Log(round_result_base_v, round_result_power_v);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {f}, {p}");
|
|
}
|
|
}
|
|
|
|
// Returns the natural (base e) logarithm of a specified number.
|
|
public static T log<T>(T f)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var base_v = Convert.ToSingle(f);
|
|
return (T)(object)MathF.Log(base_v);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var base_v = Convert.ToDouble(f);
|
|
return (T)(object)(double)Math.Log(base_v);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var base_v = Convert.ToDecimal(f);
|
|
var round_result_base_v = Math.Round((double)base_v, 28);
|
|
return (T)(object)(decimal)Math.Log(round_result_base_v);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {f}");
|
|
}
|
|
}
|
|
|
|
// Returns the base 10 logarithm of a specified number.
|
|
public static T log10<T>(T f)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var base_v = Convert.ToSingle(f);
|
|
return (T)(object)MathF.Log10(base_v);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var base_v = Convert.ToDouble(f);
|
|
return (T)(object)(double)Math.Log10(base_v);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var base_v = Convert.ToDecimal(f);
|
|
var round_result_base_v = Math.Round((double)base_v, 28);
|
|
return (T)(object)(decimal)Math.Log10(round_result_base_v);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {f}");
|
|
}
|
|
}
|
|
|
|
// Returns the smallest integer greater to or equal to /value/.
|
|
public static T ceil<T>(T value)
|
|
where T : struct
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Ceiling(Convert.ToSingle(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Ceiling(Convert.ToDouble(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Math.Ceiling(Convert.ToDecimal(value));
|
|
return (T)(object)result;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the largest integer smaller to or equal to /value/.
|
|
public static T floor<T>(T value)
|
|
where T : struct
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Floor(Convert.ToSingle(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Floor(Convert.ToDouble(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Math.Floor(Convert.ToDecimal(value));
|
|
return (T)(object)result;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns /value/ rounded to T float, double, decimal
|
|
public static T round<T>(T value)
|
|
where T : struct
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Round(Convert.ToSingle(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Round(Convert.ToDouble(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Math.Round(Convert.ToDecimal(value));
|
|
return (T)(object)result;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns /value/ rounded to T float, double, decimal
|
|
public static T round<T>(T value, int decimalPlaces)
|
|
where T : struct
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Round(Convert.ToSingle(value), decimalPlaces);
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Round(Convert.ToDouble(value), decimalPlaces);
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Math.Round(Convert.ToDecimal(value), decimalPlaces);
|
|
return (T)(object)result;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the smallest integer greater to or equal to /value/.
|
|
public static T truncate<T>(T value)
|
|
where T : struct, IComparable<T>
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = MathF.Truncate(Convert.ToSingle(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Math.Truncate(Convert.ToDouble(value));
|
|
return (T)(object)result;
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Math.Truncate(Convert.ToDecimal(value));
|
|
return (T)(object)result;
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
public static T roundUpOrDown<T>(T value, int decimalPlaces = 0)
|
|
where T : struct, IComparable<T>
|
|
{
|
|
dynamic dynamic_value = value;
|
|
double factor = Math.Pow(10, decimalPlaces); // 소숫점 자리수에 따라 곱할 값 설정, 0일 경우 소수점없이 올림 처리 한다 !!!
|
|
|
|
if (TypeHelper.NumericSignType.Positive == TypeHelper.checkNumericSignType<T>(dynamic_value))
|
|
{
|
|
return (T)(Math.Ceiling(dynamic_value * factor) / factor);
|
|
}
|
|
|
|
return (T)(Math.Floor(dynamic_value * factor) / factor);
|
|
}
|
|
|
|
// Returns the smallest integer greater to or equal to /value/.
|
|
public static T ceilToInt<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)(Int32)MathF.Ceiling(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)(Int32)Math.Ceiling(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
return (T)(object)(Int32)Math.Ceiling(result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the largest integer smaller to or equal to /value/.
|
|
public static T floorToInt<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)(Int32)MathF.Floor(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)(Int32)Math.Floor(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
return (T)(object)(Int32)Math.Floor(result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns /value/ rounded to the nearest integer.
|
|
public static T roundToInt<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)(Int32)MathF.Round(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)(Int32)Math.Round(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
return (T)(object)(Int32)Math.Round(result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns /value/ truncated to the nearest integer.
|
|
public static T truncateToInt<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result = Convert.ToSingle(value);
|
|
return (T)(object)(Int32)MathF.Truncate(result);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result = Convert.ToDouble(value);
|
|
return (T)(object)(Int32)Math.Round(result);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result = Convert.ToDecimal(value);
|
|
return (T)(object)(Int32)Math.Round(result);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Returns the sign of /value/.
|
|
public static T sign<T>(T value)
|
|
where T : struct, IConvertible
|
|
{
|
|
if (typeof(T) == typeof(float))
|
|
{
|
|
var result_v = Convert.ToSingle(value);
|
|
return (T)(object)(result_v >= 0F ? 1F : -1F);
|
|
}
|
|
else if (typeof(T) == typeof(double))
|
|
{
|
|
var result_v = Convert.ToDouble(value);
|
|
return (T)(object)(result_v >= 0D ? 1D : -1D);
|
|
}
|
|
else if (typeof(T) == typeof(decimal))
|
|
{
|
|
var result_v = Convert.ToDecimal(value);
|
|
return (T)(object)(result_v >= 0M ? 1M : -1M);
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException($"Invalid Type !!! : {value}");
|
|
}
|
|
}
|
|
|
|
// Clamps a value between a minimum generic type and maximum generic type value.
|
|
public static T clamp<T>(T value, T min, T max)
|
|
where T : IComparable<T>
|
|
{
|
|
if (value.CompareTo(min) < 0)
|
|
value = min;
|
|
else if (value.CompareTo(max) > 0)
|
|
value = max;
|
|
|
|
return value;
|
|
}
|
|
}
|