diff --git a/Nerd_STF/Mathematics/BigInteger.cs b/Nerd_STF/Mathematics/BigInteger.cs index ec95916..638ce0e 100644 --- a/Nerd_STF/Mathematics/BigInteger.cs +++ b/Nerd_STF/Mathematics/BigInteger.cs @@ -2,9 +2,15 @@ namespace Nerd_STF.Mathematics; -public readonly struct BigInteger/* : IAbsolute, IAverage, IClamp, IDivide, - ILerp, IMathOperators, IMax, IMedian, IMin, - IPresets1d, IProduct, ISubtract, ISum*/ +public readonly struct BigInteger/* : IAbsolute, IAverage, IClamp, + IComparable, IComparable, IComparable, IComparable, IComparable, + IComparable, IComparable, IComparable, IComparable, IComparable, + IComparable, IComparable, IComparable, IDivide, IEquatable, + IEquatable, IEquatable, IEquatable, IEquatable, IEquatable, IEquatable, + IEquatable, IEquatable, IEquatable, IEquatable, IEquatable, + IEquatable, ILerp, IMathOperators, IMax, + IMedian, IMin, IPresets1d, IProduct, ISubtract, + ISum*/ { public static BigInteger One => new(false, new byte[] { 1 }); public static BigInteger Zero => new(false, Array.Empty()); @@ -91,10 +97,113 @@ public readonly struct BigInteger/* : IAbsolute, IAverage (ulong)ToInt64(); + public int CompareTo(byte other) => CompareTo((BigInteger)other); + public int CompareTo(sbyte other) => CompareTo((BigInteger)other); + public int CompareTo(ushort other) => CompareTo((BigInteger)other); + public int CompareTo(short other) => CompareTo((BigInteger)other); + public int CompareTo(uint other) => CompareTo((BigInteger)other); + public int CompareTo(int other) => CompareTo((BigInteger)other); + public int CompareTo(ulong other) => CompareTo((BigInteger)other); + public int CompareTo(long other) => CompareTo((BigInteger)other); + public int CompareTo(Half other) => CompareTo((BigInteger)other); + public int CompareTo(float other) => CompareTo((BigInteger)other); + public int CompareTo(double other) => CompareTo((BigInteger)other); + public int CompareTo(decimal other) => CompareTo((BigInteger)other); + public int CompareTo(BigInteger other) + { + int compare = p_sign.CompareTo(other.p_sign); + if (compare != 0) return compare; + + compare = p_data.Length.CompareTo(other.p_data); + if (compare != 0) return compare; + + for (int i = p_data.Length - 1; i >= 0; i--) + { + compare = p_data[i].CompareTo(other.p_data[i]); + if (compare != 0) return compare; + } + + return 0; + } + public override bool Equals([NotNullWhen(true)] object? obj) + { + if (obj is null) return false; + else if (obj is BigInteger val) return Equals(val); + else if (obj is byte valUInt8) return Equals(valUInt8); + else if (obj is sbyte valInt8) return Equals(valInt8); + else if (obj is ushort valUInt16) return Equals(valUInt16); + else if (obj is short valInt16) return Equals(valInt16); + else if (obj is uint valUInt32) return Equals(valUInt32); + else if (obj is int valInt32) return Equals(valInt32); + else if (obj is ulong valUInt64) return Equals(valUInt64); + else if (obj is long valInt64) return Equals(valInt64); + else if (obj is Half valHalf) return Equals(valHalf); + else if (obj is float valSingle) return Equals(valSingle); + else if (obj is double valDouble) return Equals(valDouble); + else if (obj is decimal valDecimal) return Equals(valDecimal); + return base.Equals(obj); + } + public bool Equals(byte other) => Equals((BigInteger)other); + public bool Equals(sbyte other) => Equals((BigInteger)other); + public bool Equals(ushort other) => Equals((BigInteger)other); + public bool Equals(short other) => Equals((BigInteger)other); + public bool Equals(uint other) => Equals((BigInteger)other); + public bool Equals(int other) => Equals((BigInteger)other); + public bool Equals(ulong other) => Equals((BigInteger)other); + public bool Equals(long other) => Equals((BigInteger)other); + public bool Equals(Half other) => Equals((BigInteger)other); + public bool Equals(float other) => Equals((BigInteger)other); + public bool Equals(double other) => Equals((BigInteger)other); + public bool Equals(decimal other) => Equals((BigInteger)other); + public bool Equals(BigInteger other) => p_sign == other.p_sign; + public override int GetHashCode() => base.GetHashCode(); + public override string ToString() + { + return ToInt64().ToString(); // This isn't good because it doesn't work for numbers larger than 2^63 + } + private byte[] GetDataOfSize(int bytes) { byte[] data = new byte[bytes]; Array.Copy(p_data, data, Mathf.Min(p_data.Length, bytes)); return data; } + private byte[] TrimmedData() + { + int start = 0; + while (start < p_data.Length && p_data[start] == 0) start++; + return p_data.Skip(start).ToArray(); + } + + public static bool operator ==(BigInteger a, BigInteger b) => a.Equals(b); + public static bool operator !=(BigInteger a, BigInteger b) => !a.Equals(b); + public static bool operator >(BigInteger a, BigInteger b) => a.CompareTo(b) > 0; + public static bool operator <(BigInteger a, BigInteger b) => a.CompareTo(b) < 0; + public static bool operator >=(BigInteger a, BigInteger b) => a == b || a > b; + public static bool operator <=(BigInteger a, BigInteger b) => a == b || a < b; + + public static implicit operator BigInteger(byte val) => new(val); + public static implicit operator BigInteger(sbyte val) => new(val); + public static implicit operator BigInteger(ushort val) => new(val); + public static implicit operator BigInteger(short val) => new(val); + public static implicit operator BigInteger(uint val) => new(val); + public static implicit operator BigInteger(int val) => new(val); + public static implicit operator BigInteger(ulong val) => new(val); + public static implicit operator BigInteger(long val) => new(val); + public static explicit operator BigInteger(Half val) => new((int)val); + public static explicit operator BigInteger(float val) => new((int)val); + public static explicit operator BigInteger(double val) => new((long)val); + public static explicit operator BigInteger(decimal val) => new((long)val); + public static explicit operator byte(BigInteger val) => val.ToUInt8(); + public static explicit operator sbyte(BigInteger val) => val.ToInt8(); + public static explicit operator ushort(BigInteger val) => val.ToUInt16(); + public static explicit operator short(BigInteger val) => val.ToInt16(); + public static explicit operator uint(BigInteger val) => val.ToUInt32(); + public static explicit operator int(BigInteger val) => val.ToInt32(); + public static explicit operator ulong(BigInteger val) => val.ToUInt64(); + public static explicit operator long(BigInteger val) => val.ToInt64(); + public static explicit operator Half(BigInteger val) => (Half)val.ToInt32(); + public static explicit operator float(BigInteger val) => val.ToInt32(); + public static explicit operator double(BigInteger val) => val.ToInt64(); + public static explicit operator decimal(BigInteger val) => val.ToInt64(); }