// Decompiled with JetBrains decompiler // Type: Microsoft.Scripting.Math.BigInteger // Assembly: FiestaShark, Version=2.3.0.0, Culture=neutral, PublicKeyToken=null // MVID: 12469781-3753-4869-9C1A-117F1862B52C // Assembly location: E:\Fiesta\Emus\DragonFiesta\Tools\FiestaShark-Farbod\FiestaShark.exe using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Text; namespace Microsoft.Scripting.Math { [TypeConverter(typeof (BigInteger.TypeConvertor))] public class BigInteger : IFormattable, IComparable, IConvertible { public static readonly BigInteger Zero = new BigInteger(0, new uint[0]); public static readonly BigInteger One = new BigInteger(1, new uint[1] { 1U }); private static int bias = 1075; private static uint[] maxCharsPerDigit = new uint[37] { 0U, 0U, 31U, 20U, 15U, 13U, 12U, 11U, 10U, 10U, 9U, 9U, 8U, 8U, 8U, 8U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U }; private static uint[] groupRadixValues = new uint[37] { 0U, 0U, 2147483648U, 3486784401U, 1073741824U, 1220703125U, 2176782336U, 1977326743U, 1073741824U, 3486784401U, 1000000000U, 2357947691U, 429981696U, 815730721U, 1475789056U, 2562890625U, 268435456U, 410338673U, 612220032U, 893871739U, 1280000000U, 1801088541U, 2494357888U, 3404825447U, 191102976U, 244140625U, 308915776U, 387420489U, 481890304U, 594823321U, 729000000U, 887503681U, 1073741824U, 1291467969U, 1544804416U, 1838265625U, 2176782336U }; private const int BitsPerDigit = 32; private const ulong Base = 4294967296; private readonly short sign; private readonly uint[] data; private const int DecimalScaleFactorMask = 16711680; private const int DecimalSignMask = -2147483648; public static BigInteger Create(ulong v) { return new BigInteger(1, new uint[2] { (uint) v, (uint) (v >> 32) }); } public static BigInteger Create(uint v) { if (v == 0U) return BigInteger.Zero; if (v == 1U) return BigInteger.One; return new BigInteger(1, new uint[1]{ v }); } public static BigInteger Create(long v) { int sign = 1; ulong num; if (v < 0L) { num = (ulong) -v; sign = -1; } else num = (ulong) v; return new BigInteger(sign, new uint[2] { (uint) num, (uint) (num >> 32) }); } public static BigInteger Create(int v) { if (v == 0) return BigInteger.Zero; if (v == 1) return BigInteger.One; return v < 0 ? new BigInteger(-1, new uint[1] { (uint) -v }) : new BigInteger(1, new uint[1]{ (uint) v }); } public static BigInteger Create(Decimal v) { int[] bits = Decimal.GetBits(Decimal.Truncate(v)); int length = 3; while (length > 0 && bits[length - 1] == 0) --length; if (length == 0) return BigInteger.Zero; uint[] numArray = new uint[length]; numArray[0] = (uint) bits[0]; if (length > 1) numArray[1] = (uint) bits[1]; if (length > 2) numArray[2] = (uint) bits[2]; return new BigInteger((bits[3] & int.MinValue) != 0 ? -1 : 1, numArray); } public static BigInteger Create(byte[] v) { if (v.Length == 0) return BigInteger.Create(0); int length1 = v.Length; int num = length1 % 4; int length2 = length1 / 4 + (num == 0 ? 0 : 1); uint[] d = new uint[length2]; bool flag1 = ((int) v[length1 - 1] & 128) == 128; bool flag2 = true; int index1 = 3; int index2; for (index2 = 0; index2 < length2 - (num == 0 ? 0 : 1); ++index2) { for (int index3 = 0; index3 < 4; ++index3) { if (v[index1] != (byte) 0) flag2 = false; d[index2] <<= 8; d[index2] |= (uint) v[index1]; --index1; } index1 += 8; } if (num != 0) { if (flag1) d[length2 - 1] = uint.MaxValue; for (int index3 = length1 - 1; index3 >= length1 - num; --index3) { if (v[index3] != (byte) 0) flag2 = false; d[index2] <<= 8; d[index2] |= (uint) v[index3]; } } if (flag2) return BigInteger.Zero; if (!flag1) return new BigInteger(1, d); BigInteger.makeTwosComplement(d); return new BigInteger(-1, d); } private static bool Negative(byte[] v) { return ((uint) v[7] & 128U) > 0U; } private static ushort Exponent(byte[] v) { return (ushort) ((int) (ushort) ((uint) v[7] & (uint) sbyte.MaxValue) << 4 | (int) (ushort) ((uint) v[6] & 240U) >> 4); } private static ulong Mantissa(byte[] v) { return (ulong) (uint) ((int) v[0] | (int) v[1] << 8 | (int) v[2] << 16 | (int) v[3] << 24) | (ulong) (uint) ((int) v[4] | (int) v[5] << 8 | ((int) v[6] & 15) << 16) << 32; } public static BigInteger Create(double v) { byte[] bytes = BitConverter.GetBytes(v); ulong num1 = BigInteger.Mantissa(bytes); if (num1 == 0UL) { int num2 = (int) BigInteger.Exponent(bytes); return num2 == 0 ? BigInteger.Zero : (BigInteger.Negative(bytes) ? BigInteger.Negate(BigInteger.One) : BigInteger.One) << num2 - 1023; } int num3 = (int) BigInteger.Exponent(bytes); BigInteger bigInteger1 = BigInteger.Create(num1 | 4503599627370496UL); BigInteger bigInteger2 = num3 > BigInteger.bias ? bigInteger1 << num3 - BigInteger.bias : bigInteger1 >> BigInteger.bias - num3; return !BigInteger.Negative(bytes) ? bigInteger2 : bigInteger2 * -1; } public static implicit operator BigInteger(byte i) { return BigInteger.Create((uint) i); } public static implicit operator BigInteger(sbyte i) { return BigInteger.Create((int) i); } public static implicit operator BigInteger(short i) { return BigInteger.Create((int) i); } public static implicit operator BigInteger(ushort i) { return BigInteger.Create((uint) i); } public static implicit operator BigInteger(uint i) { return BigInteger.Create(i); } public static implicit operator BigInteger(int i) { return BigInteger.Create(i); } public static implicit operator BigInteger(ulong i) { return BigInteger.Create(i); } public static implicit operator BigInteger(long i) { return BigInteger.Create(i); } public static implicit operator BigInteger(Decimal i) { return BigInteger.Create(i); } public static implicit operator double(BigInteger i) { if ((object) i == null) throw new ArgumentNullException(nameof (i)); return i.ToFloat64(); } public static explicit operator byte(BigInteger self) { int ret; if (self.AsInt32(out ret)) return checked ((byte) ret); throw new OverflowException(); } public static explicit operator sbyte(BigInteger self) { int ret; if (self.AsInt32(out ret)) return checked ((sbyte) ret); throw new OverflowException(); } public static explicit operator ushort(BigInteger self) { int ret; if (self.AsInt32(out ret)) return checked ((ushort) ret); throw new OverflowException(); } public static explicit operator short(BigInteger self) { int ret; if (self.AsInt32(out ret)) return checked ((short) ret); throw new OverflowException(); } public static explicit operator uint(BigInteger self) { uint ret; if (self.AsUInt32(out ret)) return ret; throw new OverflowException(); } public static explicit operator int(BigInteger self) { int ret; if (self.AsInt32(out ret)) return ret; throw new OverflowException(); } public static explicit operator long(BigInteger self) { long ret; if (self.AsInt64(out ret)) return ret; throw new OverflowException(); } public static explicit operator ulong(BigInteger self) { ulong ret; if (self.AsUInt64(out ret)) return ret; throw new OverflowException(); } public static explicit operator float(BigInteger self) { if ((object) self == null) throw new ArgumentNullException(nameof (self)); return (float) self.ToFloat64(); } public static explicit operator Decimal(BigInteger self) { Decimal ret; if (self.AsDecimal(out ret)) return ret; throw new OverflowException(); } public BigInteger(BigInteger copy) { if ((object) copy == null) throw new ArgumentNullException(nameof (copy)); this.sign = copy.sign; this.data = copy.data; } public BigInteger(int sign, params uint[] data) { if (sign != -1 && sign != 0 && sign != 1) throw new ArgumentException(MathResources.InvalidArgument, nameof (sign)); if (BigInteger.GetLength(data) != 0) { if (sign == 0) throw new ArgumentException(MathResources.InvalidArgument, nameof (sign)); } else sign = 0; this.data = data; this.sign = (short) sign; } public uint[] GetBits() { if (this.sign == (short) 0) return new uint[0]; int index = this.data.Length - 1; while (index >= 0 && this.data[index] == 0U) --index; uint[] numArray = new uint[index + 1]; Array.Copy((Array) this.data, (Array) numArray, index + 1); return numArray; } public short Sign { get { return this.sign; } } public bool AsInt64(out long ret) { ret = 0L; if (this.sign == (short) 0) return true; if (this.Length > 2) return false; if (this.data.Length == 1) { ret = (long) this.sign * (long) this.data[0]; return true; } ulong num = (ulong) this.data[1] << 32 | (ulong) this.data[0]; if (num > 9223372036854775808UL || num == 9223372036854775808UL && this.sign == (short) 1) return false; ret = (long) num * (long) this.sign; return true; } public bool AsUInt32(out uint ret) { ret = 0U; if (this.sign == (short) 0) return true; if (this.sign < (short) 0 || this.Length > 1) return false; ret = this.data[0]; return true; } public bool AsUInt64(out ulong ret) { ret = 0UL; if (this.sign == (short) 0) return true; if (this.sign < (short) 0 || this.Length > 2) return false; ret = (ulong) this.data[0]; if (this.data.Length > 1) ret |= (ulong) this.data[1] << 32; return true; } public bool AsInt32(out int ret) { ret = 0; if (this.sign == (short) 0) return true; if (this.Length > 1 || this.data[0] > 2147483648U || this.data[0] == 2147483648U && this.sign == (short) 1) return false; ret = (int) this.data[0]; ret *= (int) this.sign; return true; } public bool AsDecimal(out Decimal ret) { if (this.sign == (short) 0) { ret = new Decimal(); return true; } BigInteger bigInteger = this; int num = 0; int length; for (length = this.Length; length > 3; length = bigInteger.Length) { if (num >= 28) { ret = new Decimal(); return false; } bigInteger /= (BigInteger) 10; ++num; } int lo = 0; int mid = 0; int hi = 0; if (length > 2) hi = (int) bigInteger.data[2]; if (length > 1) mid = (int) bigInteger.data[1]; if (length > 0) lo = (int) bigInteger.data[0]; ret = new Decimal(lo, mid, hi, this.sign < (short) 0, (byte) num); return true; } public uint ToUInt32() { uint ret; if (this.AsUInt32(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitUInt); } public int ToInt32() { int ret; if (this.AsInt32(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitInt); } public Decimal ToDecimal() { Decimal ret; if (this.AsDecimal(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitDecimal); } public ulong ToUInt64() { ulong ret; if (this.AsUInt64(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitULong); } public long ToInt64() { long ret; if (this.AsInt64(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitLong); } public bool TryToFloat64(out double result) { try { result = double.Parse(this.ToString(10U), NumberStyles.Number, (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat); return true; } catch { result = 0.0; return false; } } public double ToFloat64() { return double.Parse(this.ToString(10U), (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat); } public int Length { get { return BigInteger.GetLength(this.data); } } private static int GetLength(uint[] data) { int index = data.Length - 1; while (index >= 0 && data[index] == 0U) --index; return index + 1; } private static uint[] copy(uint[] v) { uint[] numArray = new uint[v.Length]; Array.Copy((Array) v, (Array) numArray, v.Length); return numArray; } private static uint[] resize(uint[] v, int len) { if (v.Length == len) return v; uint[] numArray = new uint[len]; int num = System.Math.Min(v.Length, len); for (int index = 0; index < num; ++index) numArray[index] = v[index]; return numArray; } private static uint[] InternalAdd(uint[] x, int xl, uint[] y, int yl) { uint[] v = new uint[xl]; ulong num1 = 0; int index; for (index = 0; index < yl; ++index) { ulong num2 = num1 + (ulong) x[index] + (ulong) y[index]; v[index] = (uint) num2; num1 = num2 >> 32; } for (; index < xl && num1 != 0UL; ++index) { ulong num2 = num1 + (ulong) x[index]; v[index] = (uint) num2; num1 = num2 >> 32; } if (num1 != 0UL) { v = BigInteger.resize(v, xl + 1); v[index] = (uint) num1; } else { for (; index < xl; ++index) v[index] = x[index]; } return v; } private static uint[] sub(uint[] x, int xl, uint[] y, int yl) { uint[] numArray = new uint[xl]; bool flag = false; int index; for (index = 0; index < yl; ++index) { uint maxValue = x[index]; uint num = y[index]; if (flag) { if (maxValue == 0U) { maxValue = uint.MaxValue; flag = true; } else { --maxValue; flag = false; } } if (num > maxValue) flag = true; numArray[index] = maxValue - num; } if (flag) { for (; index < xl; ++index) { uint num = x[index]; numArray[index] = num - 1U; if (num != 0U) { ++index; break; } } } for (; index < xl; ++index) numArray[index] = x[index]; return numArray; } private static uint[] add0(uint[] x, int xl, uint[] y, int yl) { return xl >= yl ? BigInteger.InternalAdd(x, xl, y, yl) : BigInteger.InternalAdd(y, yl, x, xl); } public static int Compare(BigInteger x, BigInteger y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); if ((int) x.sign == (int) y.sign) { int length1 = x.Length; int length2 = y.Length; if (length1 == length2) { for (int index = length1 - 1; index >= 0; --index) { if ((int) x.data[index] != (int) y.data[index]) return x.data[index] <= y.data[index] ? (int) -x.sign : (int) x.sign; } return 0; } return length1 <= length2 ? (int) -x.sign : (int) x.sign; } return (int) x.sign <= (int) y.sign ? -1 : 1; } public static bool operator ==(BigInteger x, int y) { return x == (BigInteger) y; } public static bool operator !=(BigInteger x, int y) { return !(x == y); } public static bool operator ==(BigInteger x, double y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); return y % 1.0 == 0.0 && x == BigInteger.Create(y); } public static bool operator ==(double x, BigInteger y) { return y == x; } public static bool operator !=(BigInteger x, double y) { return !(x == y); } public static bool operator !=(double x, BigInteger y) { return !(x == y); } public static bool operator ==(BigInteger x, BigInteger y) { return BigInteger.Compare(x, y) == 0; } public static bool operator !=(BigInteger x, BigInteger y) { return (uint) BigInteger.Compare(x, y) > 0U; } public static bool operator <(BigInteger x, BigInteger y) { return BigInteger.Compare(x, y) < 0; } public static bool operator <=(BigInteger x, BigInteger y) { return BigInteger.Compare(x, y) <= 0; } public static bool operator >(BigInteger x, BigInteger y) { return BigInteger.Compare(x, y) > 0; } public static bool operator >=(BigInteger x, BigInteger y) { return BigInteger.Compare(x, y) >= 0; } public static BigInteger Add(BigInteger x, BigInteger y) { return x + y; } public static BigInteger operator +(BigInteger x, BigInteger y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); return (int) x.sign == (int) y.sign ? new BigInteger((int) x.sign, BigInteger.add0(x.data, x.Length, y.data, y.Length)) : x - new BigInteger((int) -y.sign, y.data); } public static BigInteger Subtract(BigInteger x, BigInteger y) { return x - y; } public static BigInteger operator -(BigInteger x, BigInteger y) { int sign = BigInteger.Compare(x, y); if (sign == 0) return BigInteger.Zero; if ((int) x.sign == (int) y.sign) { uint[] numArray; switch (sign * (int) x.sign) { case -1: numArray = BigInteger.sub(y.data, y.Length, x.data, x.Length); break; case 1: numArray = BigInteger.sub(x.data, x.Length, y.data, y.Length); break; default: return BigInteger.Zero; } return new BigInteger(sign, numArray); } uint[] numArray1 = BigInteger.add0(x.data, x.Length, y.data, y.Length); return new BigInteger(sign, numArray1); } public static BigInteger Multiply(BigInteger x, BigInteger y) { return x * y; } public static BigInteger operator *(BigInteger x, BigInteger y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); int length1 = x.Length; int length2 = y.Length; int length3 = length1 + length2; uint[] data1 = x.data; uint[] data2 = y.data; uint[] numArray = new uint[length3]; for (int index1 = 0; index1 < length1; ++index1) { uint num1 = data1[index1]; int index2 = index1; ulong num2 = 0; for (int index3 = 0; index3 < length2; ++index3) { ulong num3 = num2 + (ulong) num1 * (ulong) data2[index3] + (ulong) numArray[index2]; numArray[index2++] = (uint) num3; num2 = num3 >> 32; } ulong num4; for (; num2 != 0UL; num2 = num4 >> 32) { num4 = num2 + (ulong) numArray[index2]; numArray[index2++] = (uint) num4; } } return new BigInteger((int) x.sign * (int) y.sign, numArray); } public static BigInteger Divide(BigInteger x, BigInteger y) { return x / y; } public static BigInteger operator /(BigInteger x, BigInteger y) { return BigInteger.DivRem(x, y, out BigInteger _); } public static BigInteger Mod(BigInteger x, BigInteger y) { return x % y; } public static BigInteger operator %(BigInteger x, BigInteger y) { BigInteger remainder; BigInteger.DivRem(x, y, out remainder); return remainder; } private static int GetNormalizeShift(uint value) { int num = 0; if (((int) value & -65536) == 0) { value <<= 16; num += 16; } if (((int) value & -16777216) == 0) { value <<= 8; num += 8; } if (((int) value & -268435456) == 0) { value <<= 4; num += 4; } if (((int) value & -1073741824) == 0) { value <<= 2; num += 2; } if (((int) value & int.MinValue) == 0) { value <<= 1; ++num; } return num; } [Conditional("DEBUG")] private static void TestNormalize(uint[] u, uint[] un, int shift) { BigInteger bigInteger1 = new BigInteger(1, u); BigInteger bigInteger2 = new BigInteger(1, un) >> shift; } [Conditional("DEBUG")] private static void TestDivisionStep(uint[] un, uint[] vn, uint[] q, uint[] u, uint[] v) { int length = BigInteger.GetLength(v); int normalizeShift = BigInteger.GetNormalizeShift(v[length - 1]); BigInteger bigInteger1 = new BigInteger(1, un); BigInteger bigInteger2 = new BigInteger(1, vn); BigInteger bigInteger3 = new BigInteger(1, q); BigInteger bigInteger4 = new BigInteger(1, u); BigInteger bigInteger5 = bigInteger2 * bigInteger3 + bigInteger1; BigInteger bigInteger6 = bigInteger4 << normalizeShift; } [Conditional("DEBUG")] private static void TestResult(uint[] u, uint[] v, uint[] q, uint[] r) { BigInteger bigInteger1 = new BigInteger(1, u); BigInteger bigInteger2 = new BigInteger(1, v) * new BigInteger(1, q) + new BigInteger(1, r); } private static void Normalize(uint[] u, int l, uint[] un, int shift) { uint num1 = 0; int index; if (shift > 0) { int num2 = 32 - shift; for (index = 0; index < l; ++index) { uint num3 = u[index]; un[index] = num3 << shift | num1; num1 = num3 >> num2; } } else { for (index = 0; index < l; ++index) un[index] = u[index]; } while (index < un.Length) un[index++] = 0U; if (num1 == 0U) return; un[l] = num1; } private static void Unnormalize(uint[] un, out uint[] r, int shift) { int length = BigInteger.GetLength(un); r = new uint[length]; if (shift > 0) { int num1 = 32 - shift; uint num2 = 0; for (int index = length - 1; index >= 0; --index) { uint num3 = un[index]; r[index] = num3 >> shift | num2; num2 = num3 << num1; } } else { for (int index = 0; index < length; ++index) r[index] = un[index]; } } private static void DivModUnsigned(uint[] u, uint[] v, out uint[] q, out uint[] r) { int length1 = BigInteger.GetLength(u); int length2 = BigInteger.GetLength(v); if (length2 <= 1) { if (length2 == 0) throw new DivideByZeroException(); ulong num1 = 0; uint num2 = v[0]; q = new uint[length1]; r = new uint[1]; for (int index = length1 - 1; index >= 0; --index) { ulong num3 = num1 * 4294967296UL + (ulong) u[index]; ulong num4 = num3 / (ulong) num2; num1 = num3 - num4 * (ulong) num2; q[index] = (uint) num4; } r[0] = (uint) num1; } else if (length1 >= length2) { int normalizeShift = BigInteger.GetNormalizeShift(v[length2 - 1]); uint[] un1 = new uint[length1 + 1]; uint[] un2 = new uint[length2]; BigInteger.Normalize(u, length1, un1, normalizeShift); BigInteger.Normalize(v, length2, un2, normalizeShift); q = new uint[length1 - length2 + 1]; r = (uint[]) null; for (int index1 = length1 - length2; index1 >= 0; --index1) { ulong num1 = 4294967296UL * (ulong) un1[index1 + length2] + (ulong) un1[index1 + length2 - 1]; ulong num2 = num1 / (ulong) un2[length2 - 1]; ulong num3 = num1 - num2 * (ulong) un2[length2 - 1]; while (num2 >= 4294967296UL || num2 * (ulong) un2[length2 - 2] > num3 * 4294967296UL + (ulong) un1[index1 + length2 - 2]) { --num2; num3 += (ulong) un2[length2 - 1]; if (num3 >= 4294967296UL) break; } long num4 = 0; for (int index2 = 0; index2 < length2; ++index2) { ulong num5 = (ulong) un2[index2] * num2; long num6 = (long) un1[index2 + index1] - (long) (uint) num5 - num4; un1[index2 + index1] = (uint) num6; num4 = (long) (num5 >> 32) - (num6 >> 32); } long num7 = (long) un1[index1 + length2] - num4; un1[index1 + length2] = (uint) num7; q[index1] = (uint) num2; if (num7 < 0L) { --q[index1]; ulong num5 = 0; for (int index2 = 0; index2 < length2; ++index2) { ulong num6 = (ulong) un2[index2] + (ulong) un1[index1 + index2] + num5; un1[index1 + index2] = (uint) num6; num5 = num6 >> 32; } ulong num8 = num5 + (ulong) un1[index1 + length2]; un1[index1 + length2] = (uint) num8; } } BigInteger.Unnormalize(un1, out r, normalizeShift); } else { q = new uint[1]; r = u; } } public static BigInteger DivRem(BigInteger x, BigInteger y, out BigInteger remainder) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); uint[] q; uint[] r; BigInteger.DivModUnsigned(x.data, y.data, out q, out r); remainder = new BigInteger((int) x.sign, r); return new BigInteger((int) x.sign * (int) y.sign, q); } private static uint div(uint[] n, ref int nl, uint d) { ulong num1 = 0; int index = nl; bool flag = false; while (--index >= 0) { ulong num2 = num1 << 32 | (ulong) n[index]; uint num3 = (uint) (num2 / (ulong) d); n[index] = num3; if (num3 == 0U) { if (!flag) --nl; } else flag = true; num1 = num2 % (ulong) d; } return (uint) num1; } private static uint extend(uint v, ref bool seenNonZero) { if (seenNonZero) return ~v; if (v == 0U) return 0; seenNonZero = true; return (uint) (~(int) v + 1); } private static uint getOne(bool isNeg, uint[] data, int i, ref bool seenNonZero) { if (i < data.Length) { uint v = data[i]; return !isNeg ? v : BigInteger.extend(v, ref seenNonZero); } return !isNeg ? 0U : uint.MaxValue; } private static uint[] makeTwosComplement(uint[] d) { int index = 0; uint num = 0; for (; index < d.Length; ++index) { num = (uint) (~(int) d[index] + 1); d[index] = num; if (num != 0U) { ++index; break; } } if (num != 0U) { for (; index < d.Length; ++index) d[index] = ~d[index]; } else { d = BigInteger.resize(d, d.Length + 1); d[d.Length - 1] = 1U; } return d; } public static BigInteger BitwiseAnd(BigInteger x, BigInteger y) { return x & y; } public static BigInteger operator &(BigInteger x, BigInteger y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); int length1 = x.Length; int length2 = y.Length; uint[] data1 = x.data; uint[] data2 = y.data; int length3 = System.Math.Max(length1, length2); uint[] d = new uint[length3]; bool isNeg1 = x.sign == (short) -1; bool isNeg2 = y.sign == (short) -1; bool seenNonZero1 = false; bool seenNonZero2 = false; for (int i = 0; i < length3; ++i) { uint one1 = BigInteger.getOne(isNeg1, data1, i, ref seenNonZero1); uint one2 = BigInteger.getOne(isNeg2, data2, i, ref seenNonZero2); d[i] = one1 & one2; } if (isNeg1 & isNeg2) return new BigInteger(-1, BigInteger.makeTwosComplement(d)); int num = isNeg1 | isNeg2 ? 1 : 0; return new BigInteger(1, d); } public static BigInteger BitwiseOr(BigInteger x, BigInteger y) { return x | y; } public static BigInteger operator |(BigInteger x, BigInteger y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); int length1 = x.Length; int length2 = y.Length; uint[] data1 = x.data; uint[] data2 = y.data; int length3 = System.Math.Max(length1, length2); uint[] d = new uint[length3]; bool isNeg1 = x.sign == (short) -1; bool isNeg2 = y.sign == (short) -1; bool seenNonZero1 = false; bool seenNonZero2 = false; for (int i = 0; i < length3; ++i) { uint one1 = BigInteger.getOne(isNeg1, data1, i, ref seenNonZero1); uint one2 = BigInteger.getOne(isNeg2, data2, i, ref seenNonZero2); d[i] = one1 | one2; } if (isNeg1 & isNeg2) return new BigInteger(-1, BigInteger.makeTwosComplement(d)); return isNeg1 | isNeg2 ? new BigInteger(-1, BigInteger.makeTwosComplement(d)) : new BigInteger(1, d); } public static BigInteger Xor(BigInteger x, BigInteger y) { return x ^ y; } public static BigInteger operator ^(BigInteger x, BigInteger y) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if ((object) y == null) throw new ArgumentNullException(nameof (y)); int length1 = x.Length; int length2 = y.Length; uint[] data1 = x.data; uint[] data2 = y.data; int length3 = System.Math.Max(length1, length2); uint[] d = new uint[length3]; bool isNeg1 = x.sign == (short) -1; bool isNeg2 = y.sign == (short) -1; bool seenNonZero1 = false; bool seenNonZero2 = false; for (int i = 0; i < length3; ++i) { uint one1 = BigInteger.getOne(isNeg1, data1, i, ref seenNonZero1); uint one2 = BigInteger.getOne(isNeg2, data2, i, ref seenNonZero2); d[i] = one1 ^ one2; } if (isNeg1 & isNeg2) return new BigInteger(1, d); return isNeg1 | isNeg2 ? new BigInteger(-1, BigInteger.makeTwosComplement(d)) : new BigInteger(1, d); } public static BigInteger LeftShift(BigInteger x, int shift) { return x << shift; } public static BigInteger operator <<(BigInteger x, int shift) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if (shift == 0) return x; if (shift < 0) return x >> -shift; int num1 = shift / 32; int num2 = shift - num1 * 32; int length = x.Length; uint[] data = x.data; uint[] numArray = new uint[length + num1 + 1]; if (num2 == 0) { for (int index = 0; index < length; ++index) numArray[index + num1] = data[index]; } else { int num3 = 32 - num2; uint num4 = 0; int index; for (index = 0; index < length; ++index) { uint num5 = data[index]; numArray[index + num1] = num5 << num2 | num4; num4 = num5 >> num3; } numArray[index + num1] = num4; } return new BigInteger((int) x.sign, numArray); } public static BigInteger RightShift(BigInteger x, int shift) { return x >> shift; } public static BigInteger operator >>(BigInteger x, int shift) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); if (shift == 0) return x; if (shift < 0) return x << -shift; int num1 = shift / 32; int num2 = shift - num1 * 32; int length1 = x.Length; uint[] data = x.data; int length2 = length1 - num1; if (length2 < 0) length2 = 0; uint[] numArray = new uint[length2]; if (num2 == 0) { for (int index = length1 - 1; index >= num1; --index) numArray[index - num1] = data[index]; } else { int num3 = 32 - num2; uint num4 = 0; for (int index = length1 - 1; index >= num1; --index) { uint num5 = data[index]; numArray[index - num1] = num5 >> num2 | num4; num4 = num5 << num3; } } return new BigInteger((int) x.sign, numArray); } public static BigInteger Negate(BigInteger x) { return -x; } public static BigInteger operator -(BigInteger x) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); return new BigInteger((int) -x.sign, x.data); } public BigInteger OnesComplement() { return ~this; } public static BigInteger operator ~(BigInteger x) { if ((object) x == null) throw new ArgumentNullException(nameof (x)); return -(x + BigInteger.One); } public BigInteger Abs() { return this.sign == (short) -1 ? -this : this; } public BigInteger Power(int exp) { if (exp == 0) return BigInteger.One; if (exp < 0) throw new ArgumentOutOfRangeException(MathResources.NonNegativePower); BigInteger bigInteger = this; BigInteger one = BigInteger.One; for (; exp != 0; exp >>= 1) { if ((exp & 1) != 0) one *= bigInteger; if (exp != 1) bigInteger = bigInteger.Square(); else break; } return one; } public BigInteger ModPow(int power, BigInteger mod) { if ((object) mod == null) throw new ArgumentNullException(nameof (mod)); if (power < 0) throw new ArgumentOutOfRangeException(MathResources.NonNegativePower); BigInteger bigInteger1 = this; BigInteger bigInteger2 = BigInteger.One % mod; for (; power != 0; power >>= 1) { if ((power & 1) != 0) bigInteger2 = bigInteger2 * bigInteger1 % mod; if (power != 1) bigInteger1 = bigInteger1.Square() % mod; else break; } return bigInteger2; } public BigInteger ModPow(BigInteger power, BigInteger mod) { if ((object) power == null) throw new ArgumentNullException(nameof (power)); if ((object) mod == null) throw new ArgumentNullException(nameof (mod)); if (power < (BigInteger) 0) throw new ArgumentOutOfRangeException(MathResources.NonNegativePower); BigInteger bigInteger1 = this; BigInteger bigInteger2 = BigInteger.One % mod; while (power != BigInteger.Zero) { if (power.IsOdd()) bigInteger2 = bigInteger2 * bigInteger1 % mod; if (!(power == BigInteger.One)) { bigInteger1 = bigInteger1.Square() % mod; power >>= 1; } else break; } return bigInteger2; } public BigInteger Square() { return this * this; } public override string ToString() { return this.ToString(10U); } public string ToString(uint radix) { if (radix < 2U) throw new ArgumentOutOfRangeException(nameof (radix), (object) radix, MathResources.RadixLessThan2); if (radix > 36U) throw new ArgumentOutOfRangeException(nameof (radix), (object) radix, MathResources.RadixGreaterThan36); if (this.Length == 0) return "0"; List uintList1 = new List(); uint[] n = BigInteger.copy(this.data); int length = this.Length; uint groupRadixValue = BigInteger.groupRadixValues[(int) radix]; while (length > 0) { uint num = BigInteger.div(n, ref length, groupRadixValue); uintList1.Add(num); } StringBuilder buf = new StringBuilder(); if (this.sign == (short) -1) buf.Append("-"); int num1 = uintList1.Count - 1; char[] tmp = new char[(int) BigInteger.maxCharsPerDigit[(int) radix]]; List uintList2 = uintList1; int index = num1; int num2 = index - 1; BigInteger.AppendRadix(uintList2[index], radix, tmp, buf, false); while (num2 >= 0) BigInteger.AppendRadix(uintList1[num2--], radix, tmp, buf, true); return buf.ToString(); } private static void AppendRadix( uint rem, uint radix, char[] tmp, StringBuilder buf, bool leadingZeros) { int length = tmp.Length; int startIndex; uint num; for (startIndex = length; startIndex > 0 && (leadingZeros || rem != 0U); tmp[--startIndex] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(int) num]) { num = rem % radix; rem /= radix; } if (leadingZeros) buf.Append(tmp); else buf.Append(tmp, startIndex, length - startIndex); } public override int GetHashCode() { if (this.data.Length == 0) return 0; return this.IsNegative() ? -(int) this.data[0] : (int) this.data[0]; } public override bool Equals(object obj) { BigInteger bigInteger = obj as BigInteger; return (object) bigInteger != null && this == bigInteger; } public bool IsNegative() { return this.sign < (short) 0; } public bool IsZero() { return this.sign == (short) 0; } public bool IsPositive() { return this.sign > (short) 0; } private bool IsOdd() { return this.data != null && this.data.Length != 0 && (this.data[0] & 1U) > 0U; } public int CompareTo(object obj) { if (obj == null) return 1; BigInteger y = obj as BigInteger; if ((object) y == null) throw new ArgumentException(MathResources.ExpectedInteger); return BigInteger.Compare(this, y); } public TypeCode GetTypeCode() { return TypeCode.Object; } public bool ToBoolean(IFormatProvider provider) { return this != BigInteger.Zero; } public byte ToByte(IFormatProvider provider) { uint ret; if (this.AsUInt32(out ret) && ((long) ret & -256L) == 0L) return (byte) ret; throw new OverflowException(MathResources.BigIntWontFitByte); } public byte[] ToByteArray() { if (this.sign == (short) 0) return new byte[1]; uint[] d; byte num1; if ((short) -1 == this.sign) { d = (uint[]) this.data.Clone(); BigInteger.makeTwosComplement(d); num1 = byte.MaxValue; } else { d = this.data; num1 = (byte) 0; } byte[] numArray1 = new byte[4 * d.Length]; int num2 = 0; for (int index1 = 0; index1 < d.Length; ++index1) { uint num3 = d[index1]; for (int index2 = 0; index2 < 4; ++index2) { numArray1[num2++] = (byte) (num3 & (uint) byte.MaxValue); num3 >>= 8; } } int index = numArray1.Length - 1; while (index > 0 && (int) numArray1[index] == (int) num1) --index; bool flag = ((int) numArray1[index] & 128) != ((int) num1 & 128); byte[] numArray2 = new byte[index + 1 + (flag ? 1 : 0)]; Array.Copy((Array) numArray1, (Array) numArray2, index + 1); if (flag) numArray2[numArray2.Length - 1] = num1; return numArray2; } public char ToChar(IFormatProvider provider) { int ret; if (this.AsInt32(out ret) && ret <= (int) ushort.MaxValue && ret >= 0) return (char) ret; throw new OverflowException(MathResources.BigIntWontFitChar); } public DateTime ToDateTime(IFormatProvider provider) { throw new NotImplementedException(); } public Decimal ToDecimal(IFormatProvider provider) { Decimal ret; if (this.AsDecimal(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitDecimal); } public double ToDouble(IFormatProvider provider) { return this.ToFloat64(); } public short ToInt16(IFormatProvider provider) { int ret; if (this.AsInt32(out ret) && ret <= (int) short.MaxValue && ret >= (int) short.MinValue) return (short) ret; throw new OverflowException(MathResources.BigIntWontFitShort); } public int ToInt32(IFormatProvider provider) { int ret; if (this.AsInt32(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitInt); } public long ToInt64(IFormatProvider provider) { long ret; if (this.AsInt64(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitLong); } public sbyte ToSByte(IFormatProvider provider) { int ret; if (this.AsInt32(out ret) && ret <= (int) sbyte.MaxValue && ret >= (int) sbyte.MinValue) return (sbyte) ret; throw new OverflowException(MathResources.BigIntWontFitSByte); } public float ToSingle(IFormatProvider provider) { return (float) this.ToDouble(provider); } public string ToString(IFormatProvider provider) { return this.ToString(); } public object ToType(Type conversionType, IFormatProvider provider) { if (conversionType == typeof (BigInteger)) return (object) this; throw new NotImplementedException(); } public ushort ToUInt16(IFormatProvider provider) { uint ret; if (this.AsUInt32(out ret) && ret <= (uint) ushort.MaxValue) return (ushort) ret; throw new OverflowException(MathResources.BigIntWontFitUShort); } public uint ToUInt32(IFormatProvider provider) { uint ret; if (this.AsUInt32(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitUInt); } public ulong ToUInt64(IFormatProvider provider) { ulong ret; if (this.AsUInt64(out ret)) return ret; throw new OverflowException(MathResources.BigIntWontFitULong); } string IFormattable.ToString(string format, IFormatProvider formatProvider) { if (format == null) return this.ToString(); switch (format[0]) { case 'D': case 'd': if (format.Length <= 1) return this.ToString(10U); int int32_1 = Convert.ToInt32(format.Substring(1), (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat); string str1 = this.ToString(10U); if (str1.Length >= int32_1) return str1; string str2 = new string('0', int32_1 - str1.Length); return str1[0] != '-' ? str2 + str1 : "-" + str2 + str1.Substring(1); case 'X': case 'x': StringBuilder stringBuilder = new StringBuilder(this.ToString(16U)); if (format[0] == 'x') { for (int index = 0; index < stringBuilder.Length; ++index) { if (stringBuilder[index] >= 'A' && stringBuilder[index] <= 'F') stringBuilder[index] = char.ToLowerInvariant(stringBuilder[index]); } } if (format.Length > 1) { int int32_2 = Convert.ToInt32(format.Substring(1), (IFormatProvider) CultureInfo.InvariantCulture.NumberFormat); if (stringBuilder.Length < int32_2) { string str3 = new string('0', int32_2 - stringBuilder.Length); if (stringBuilder[0] != '-') stringBuilder.Insert(0, str3); else stringBuilder.Insert(1, str3); } } return stringBuilder.ToString(); default: throw new NotImplementedException(MathResources.FormatNotImplemented); } } private class TypeConvertor : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof (BigInteger)) return true; switch (Type.GetTypeCode(sourceType)) { case TypeCode.Empty: case TypeCode.Object: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.DateTime: return false; default: return true; } } public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value) { if (value != null) { Type type = value.GetType(); if (type == typeof (BigInteger)) return value; switch (Type.GetTypeCode(type)) { case TypeCode.Char: return (object) BigInteger.Create((int) (char) value); case TypeCode.SByte: return (object) BigInteger.Create((int) (sbyte) value); case TypeCode.Byte: return (object) BigInteger.Create((int) (byte) value); case TypeCode.Int16: return (object) BigInteger.Create((int) (short) value); case TypeCode.UInt16: return (object) BigInteger.Create((int) (ushort) value); case TypeCode.Int32: return (object) BigInteger.Create((int) value); case TypeCode.UInt32: return (object) BigInteger.Create((uint) value); case TypeCode.Int64: return (object) BigInteger.Create((long) value); case TypeCode.UInt64: return (object) BigInteger.Create((ulong) value); case TypeCode.Single: return (object) BigInteger.Create((double) (float) value); case TypeCode.Double: return (object) BigInteger.Create((double) value); case TypeCode.Decimal: return (object) BigInteger.Create((Decimal) value); } } return base.ConvertFrom(context, culture, value); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof (BigInteger)) return true; switch (Type.GetTypeCode(destinationType)) { case TypeCode.Empty: case TypeCode.Object: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.DateTime: return false; default: return true; } } public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (value != null) { BigInteger bigInteger = (BigInteger) value; Type type = destinationType; if (type == typeof (BigInteger)) return value; switch (Type.GetTypeCode(type)) { case TypeCode.Char: return (object) bigInteger.ToChar((IFormatProvider) null); case TypeCode.SByte: return (object) bigInteger.ToSByte((IFormatProvider) null); case TypeCode.Byte: return (object) bigInteger.ToByte((IFormatProvider) null); case TypeCode.Int16: return (object) bigInteger.ToInt16((IFormatProvider) null); case TypeCode.UInt16: return (object) bigInteger.ToUInt16((IFormatProvider) null); case TypeCode.Int32: return (object) bigInteger.ToInt32((IFormatProvider) null); case TypeCode.UInt32: return (object) bigInteger.ToUInt32((IFormatProvider) null); case TypeCode.Int64: return (object) bigInteger.ToInt64((IFormatProvider) null); case TypeCode.UInt64: return (object) bigInteger.ToUInt64((IFormatProvider) null); case TypeCode.Single: return (object) bigInteger.ToSingle((IFormatProvider) null); case TypeCode.Double: return (object) bigInteger.ToDouble((IFormatProvider) null); case TypeCode.Decimal: return (object) bigInteger.ToDecimal((IFormatProvider) null); } } return base.ConvertTo(context, culture, value, destinationType); } } } }