593 lines
11 KiB
C#
593 lines
11 KiB
C#
using System.Diagnostics;
|
|
using System.Globalization;
|
|
|
|
namespace System
|
|
{
|
|
[Serializable]
|
|
public struct Half : IComparable, IFormattable, IConvertible, IComparable<Half>, IEquatable<Half>
|
|
{
|
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
|
public ushort internalValue;
|
|
|
|
public static readonly Half Epsilon = ToHalf(1);
|
|
|
|
public static readonly Half MaxValue = ToHalf(31743);
|
|
|
|
public static readonly Half MinValue = ToHalf(64511);
|
|
|
|
public static readonly Half NaN = ToHalf(65024);
|
|
|
|
public static readonly Half NegativeInfinity = ToHalf(64512);
|
|
|
|
public static readonly Half PositiveInfinity = ToHalf(31744);
|
|
|
|
public Half(float value)
|
|
{
|
|
this = HalfHelper.SingleToHalf(value);
|
|
}
|
|
|
|
public Half(int value)
|
|
: this((float)value)
|
|
{
|
|
}
|
|
|
|
public Half(long value)
|
|
: this((float)value)
|
|
{
|
|
}
|
|
|
|
public Half(double value)
|
|
: this((float)value)
|
|
{
|
|
}
|
|
|
|
public Half(decimal value)
|
|
: this((float)value)
|
|
{
|
|
}
|
|
|
|
public Half(uint value)
|
|
: this((float)value)
|
|
{
|
|
}
|
|
|
|
public Half(ulong value)
|
|
: this((float)value)
|
|
{
|
|
}
|
|
|
|
public static Half Negate(Half half)
|
|
{
|
|
return -half;
|
|
}
|
|
|
|
public static Half Add(Half half1, Half half2)
|
|
{
|
|
return half1 + half2;
|
|
}
|
|
|
|
public static Half Subtract(Half half1, Half half2)
|
|
{
|
|
return half1 - half2;
|
|
}
|
|
|
|
public static Half Multiply(Half half1, Half half2)
|
|
{
|
|
return half1 * half2;
|
|
}
|
|
|
|
public static Half Divide(Half half1, Half half2)
|
|
{
|
|
return half1 / half2;
|
|
}
|
|
|
|
public static Half operator +(Half half)
|
|
{
|
|
return half;
|
|
}
|
|
|
|
public static Half operator -(Half half)
|
|
{
|
|
return HalfHelper.Negate(half);
|
|
}
|
|
|
|
public static Half operator ++(Half half)
|
|
{
|
|
return (Half)((float)half + 1f);
|
|
}
|
|
|
|
public static Half operator --(Half half)
|
|
{
|
|
return (Half)((float)half - 1f);
|
|
}
|
|
|
|
public static Half operator +(Half half1, Half half2)
|
|
{
|
|
return (Half)((float)half1 + (float)half2);
|
|
}
|
|
|
|
public static Half operator -(Half half1, Half half2)
|
|
{
|
|
return (Half)((float)half1 - (float)half2);
|
|
}
|
|
|
|
public static Half operator *(Half half1, Half half2)
|
|
{
|
|
return (Half)((float)half1 * (float)half2);
|
|
}
|
|
|
|
public static Half operator /(Half half1, Half half2)
|
|
{
|
|
return (Half)((float)half1 / (float)half2);
|
|
}
|
|
|
|
public static bool operator ==(Half half1, Half half2)
|
|
{
|
|
if (!IsNaN(half1))
|
|
{
|
|
return half1.internalValue == half2.internalValue;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool operator !=(Half half1, Half half2)
|
|
{
|
|
return half1.internalValue != half2.internalValue;
|
|
}
|
|
|
|
public static bool operator <(Half half1, Half half2)
|
|
{
|
|
return (float)half1 < (float)half2;
|
|
}
|
|
|
|
public static bool operator >(Half half1, Half half2)
|
|
{
|
|
return (float)half1 > (float)half2;
|
|
}
|
|
|
|
public static bool operator <=(Half half1, Half half2)
|
|
{
|
|
if (!(half1 == half2))
|
|
{
|
|
return half1 < half2;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static bool operator >=(Half half1, Half half2)
|
|
{
|
|
if (!(half1 == half2))
|
|
{
|
|
return half1 > half2;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static implicit operator Half(byte value)
|
|
{
|
|
return new Half((float)(int)value);
|
|
}
|
|
|
|
public static implicit operator Half(short value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static implicit operator Half(char value)
|
|
{
|
|
return new Half((float)(int)value);
|
|
}
|
|
|
|
public static implicit operator Half(int value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static implicit operator Half(long value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static explicit operator Half(float value)
|
|
{
|
|
return new Half(value);
|
|
}
|
|
|
|
public static explicit operator Half(double value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static explicit operator Half(decimal value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static explicit operator byte(Half value)
|
|
{
|
|
return (byte)(float)value;
|
|
}
|
|
|
|
public static explicit operator char(Half value)
|
|
{
|
|
return (char)(float)value;
|
|
}
|
|
|
|
public static explicit operator short(Half value)
|
|
{
|
|
return (short)(float)value;
|
|
}
|
|
|
|
public static explicit operator int(Half value)
|
|
{
|
|
return (int)(float)value;
|
|
}
|
|
|
|
public static explicit operator long(Half value)
|
|
{
|
|
return (long)(float)value;
|
|
}
|
|
|
|
public static implicit operator float(Half value)
|
|
{
|
|
return HalfHelper.HalfToSingle(value);
|
|
}
|
|
|
|
public static implicit operator double(Half value)
|
|
{
|
|
return (float)value;
|
|
}
|
|
|
|
public static explicit operator decimal(Half value)
|
|
{
|
|
return (decimal)(float)value;
|
|
}
|
|
|
|
public static implicit operator Half(sbyte value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static implicit operator Half(ushort value)
|
|
{
|
|
return new Half((float)(int)value);
|
|
}
|
|
|
|
public static implicit operator Half(uint value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static implicit operator Half(ulong value)
|
|
{
|
|
return new Half((float)value);
|
|
}
|
|
|
|
public static explicit operator sbyte(Half value)
|
|
{
|
|
return (sbyte)(float)value;
|
|
}
|
|
|
|
public static explicit operator ushort(Half value)
|
|
{
|
|
return (ushort)(float)value;
|
|
}
|
|
|
|
public static explicit operator uint(Half value)
|
|
{
|
|
return (uint)(float)value;
|
|
}
|
|
|
|
public static explicit operator ulong(Half value)
|
|
{
|
|
return (ulong)(float)value;
|
|
}
|
|
|
|
public int CompareTo(Half other)
|
|
{
|
|
int result = 0;
|
|
if (this < other)
|
|
{
|
|
result = -1;
|
|
}
|
|
else if (this > other)
|
|
{
|
|
result = 1;
|
|
}
|
|
else if (this != other)
|
|
{
|
|
if (!IsNaN(this))
|
|
{
|
|
result = 1;
|
|
}
|
|
else if (!IsNaN(other))
|
|
{
|
|
result = -1;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int CompareTo(object obj)
|
|
{
|
|
int num = 0;
|
|
if (obj == null)
|
|
{
|
|
return 1;
|
|
}
|
|
if (obj is Half)
|
|
{
|
|
return CompareTo((Half)obj);
|
|
}
|
|
throw new ArgumentException("Object must be of type Half.");
|
|
}
|
|
|
|
public bool Equals(Half other)
|
|
{
|
|
if (!(other == this))
|
|
{
|
|
if (IsNaN(other))
|
|
{
|
|
return IsNaN(this);
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
bool result = false;
|
|
if (obj is Half half && (half == this || (IsNaN(half) && IsNaN(this))))
|
|
{
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return internalValue.GetHashCode();
|
|
}
|
|
|
|
public TypeCode GetTypeCode()
|
|
{
|
|
return (TypeCode)255;
|
|
}
|
|
|
|
public static byte[] GetBytes(Half value)
|
|
{
|
|
return BitConverter.GetBytes(value.internalValue);
|
|
}
|
|
|
|
public static ushort GetBits(Half value)
|
|
{
|
|
return value.internalValue;
|
|
}
|
|
|
|
public static Half ToHalf(byte[] value, int startIndex)
|
|
{
|
|
return ToHalf((ushort)BitConverter.ToInt16(value, startIndex));
|
|
}
|
|
|
|
public static Half ToHalf(ushort bits)
|
|
{
|
|
return new Half
|
|
{
|
|
internalValue = bits
|
|
};
|
|
}
|
|
|
|
public static int Sign(Half value)
|
|
{
|
|
if (value < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
if (value > 0)
|
|
{
|
|
return 1;
|
|
}
|
|
if (value != 0)
|
|
{
|
|
throw new ArithmeticException("Function does not accept floating point Not-a-Number values.");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public static Half Abs(Half value)
|
|
{
|
|
return HalfHelper.Abs(value);
|
|
}
|
|
|
|
public static Half Max(Half value1, Half value2)
|
|
{
|
|
if (!(value1 < value2))
|
|
{
|
|
return value1;
|
|
}
|
|
return value2;
|
|
}
|
|
|
|
public static Half Min(Half value1, Half value2)
|
|
{
|
|
if (!(value1 < value2))
|
|
{
|
|
return value2;
|
|
}
|
|
return value1;
|
|
}
|
|
|
|
public static bool IsNaN(Half half)
|
|
{
|
|
return HalfHelper.IsNaN(half);
|
|
}
|
|
|
|
public static bool IsInfinity(Half half)
|
|
{
|
|
return HalfHelper.IsInfinity(half);
|
|
}
|
|
|
|
public static bool IsNegativeInfinity(Half half)
|
|
{
|
|
return HalfHelper.IsNegativeInfinity(half);
|
|
}
|
|
|
|
public static bool IsPositiveInfinity(Half half)
|
|
{
|
|
return HalfHelper.IsPositiveInfinity(half);
|
|
}
|
|
|
|
public static Half Parse(string value)
|
|
{
|
|
return (Half)float.Parse(value, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
public static Half Parse(string value, IFormatProvider provider)
|
|
{
|
|
return (Half)float.Parse(value, provider);
|
|
}
|
|
|
|
public static Half Parse(string value, NumberStyles style)
|
|
{
|
|
return (Half)float.Parse(value, style, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
public static Half Parse(string value, NumberStyles style, IFormatProvider provider)
|
|
{
|
|
return (Half)float.Parse(value, style, provider);
|
|
}
|
|
|
|
public static bool TryParse(string value, out Half result)
|
|
{
|
|
if (float.TryParse(value, out var result2))
|
|
{
|
|
result = (Half)result2;
|
|
return true;
|
|
}
|
|
result = default(Half);
|
|
return false;
|
|
}
|
|
|
|
public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out Half result)
|
|
{
|
|
bool result2 = false;
|
|
if (float.TryParse(value, style, provider, out var result3))
|
|
{
|
|
result = (Half)result3;
|
|
result2 = true;
|
|
}
|
|
else
|
|
{
|
|
result = default(Half);
|
|
}
|
|
return result2;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return ((float)this).ToString(CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
public string ToString(IFormatProvider formatProvider)
|
|
{
|
|
return ((float)this).ToString(formatProvider);
|
|
}
|
|
|
|
public string ToString(string format)
|
|
{
|
|
return ((float)this).ToString(format, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
public string ToString(string format, IFormatProvider formatProvider)
|
|
{
|
|
return ((float)this).ToString(format, formatProvider);
|
|
}
|
|
|
|
float IConvertible.ToSingle(IFormatProvider provider)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
TypeCode IConvertible.GetTypeCode()
|
|
{
|
|
return GetTypeCode();
|
|
}
|
|
|
|
bool IConvertible.ToBoolean(IFormatProvider provider)
|
|
{
|
|
return Convert.ToBoolean(this);
|
|
}
|
|
|
|
byte IConvertible.ToByte(IFormatProvider provider)
|
|
{
|
|
return Convert.ToByte(this);
|
|
}
|
|
|
|
char IConvertible.ToChar(IFormatProvider provider)
|
|
{
|
|
throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "Char"));
|
|
}
|
|
|
|
DateTime IConvertible.ToDateTime(IFormatProvider provider)
|
|
{
|
|
throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "DateTime"));
|
|
}
|
|
|
|
decimal IConvertible.ToDecimal(IFormatProvider provider)
|
|
{
|
|
return Convert.ToDecimal(this);
|
|
}
|
|
|
|
double IConvertible.ToDouble(IFormatProvider provider)
|
|
{
|
|
return Convert.ToDouble(this);
|
|
}
|
|
|
|
short IConvertible.ToInt16(IFormatProvider provider)
|
|
{
|
|
return Convert.ToInt16(this);
|
|
}
|
|
|
|
int IConvertible.ToInt32(IFormatProvider provider)
|
|
{
|
|
return Convert.ToInt32(this);
|
|
}
|
|
|
|
long IConvertible.ToInt64(IFormatProvider provider)
|
|
{
|
|
return Convert.ToInt64(this);
|
|
}
|
|
|
|
sbyte IConvertible.ToSByte(IFormatProvider provider)
|
|
{
|
|
return Convert.ToSByte(this);
|
|
}
|
|
|
|
string IConvertible.ToString(IFormatProvider provider)
|
|
{
|
|
return Convert.ToString(this, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
|
|
{
|
|
return ((IConvertible)(float)this).ToType(conversionType, provider);
|
|
}
|
|
|
|
ushort IConvertible.ToUInt16(IFormatProvider provider)
|
|
{
|
|
return Convert.ToUInt16(this);
|
|
}
|
|
|
|
uint IConvertible.ToUInt32(IFormatProvider provider)
|
|
{
|
|
return Convert.ToUInt32(this);
|
|
}
|
|
|
|
ulong IConvertible.ToUInt64(IFormatProvider provider)
|
|
{
|
|
return Convert.ToUInt64(this);
|
|
}
|
|
}
|
|
}
|