[Serializable, StructLayout(LayoutKind.Sequential), ComVisible(false)]
public struct BigInteger : IFormattable, IEquatable<BigInteger>, IComparable<BigInteger>, IComparable
{
#region Fields
private const int DecimalScaleFactorMask = 0xff0000;
private const int DecimalSignMask = -2147483648;
private const int BitsPerDigit = 0x20;
private const ulong Base = 0x100000000L;
private const int UpperBoundForSchoolBookMultiplicationDigits = 0x40;
private const int ForceSchoolBookMultiplicationThresholdDigits = 8;
private static readonly uint[] maxCharsPerDigit;
private static readonly uint[] groupRadixValues;
private static readonly uint[] zeroArray;
private readonly short _sign;
private readonly uint[] _data;
private int _length;
#endregion
#region Ctors
static BigInteger()
{
maxCharsPerDigit = new uint[]
{
0, 0, 0x1f, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8,
7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6
};
groupRadixValues = new uint[]
{
0, 0, 0x80000000, 0xcfd41b91, 0x40000000, 0x48c27395, 0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91, 0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021, 0x57f6c100, 0x98c29b81,
0x10000000, 0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d, 0x94ace180, 0xcaf18367, 0xb640000, 0xe8d4a51, 0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41,
0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x81bf1000
};
zeroArray = new uint[0];
}
public BigInteger(int value)
{
if (value == 0)
{
this._sign = 0;
this._data = new uint[0];
}
else if (value < 0)
{
this._sign = -1;
this._data = new uint[] { (uint)-value };
}
else
{
this._sign = 1;
this._data = new uint[] { (uint)value };
}
this._length = -1;
}
public BigInteger(long value)
{
ulong num = 0L;
if (value < 0L)
{
num = (ulong)-value;
this._sign = -1;
}
else if (value > 0L)
{
num = (ulong)value;
this._sign = 1;
}
else
{
this._sign = 0;
}
if (num >= 0x100000000L)
{
this._data = new uint[] { (uint)num, (uint)(num >> 0x20) };
}
else
{
this._data = new uint[] { (uint)num };
}
this._length = -1;
}
[CLSCompliant(false)]
public BigInteger(uint value)
{
if (value == 0)
{
this._sign = 0;
}
else
{
this._sign = 1;
}
this._data = new uint[] { value };
this._length = -1;
}
[CLSCompliant(false)]
public BigInteger(ulong value)
{
if (value == 0L)
{
this._sign = 0;
}
else
{
this._sign = 1;
}
if (value >= 0x100000000L)
{
this._data = new uint[] { (uint)value, (uint)(value >> 0x20) };
}
else
{
this._data = new uint[] { (uint)value };
}
this._length = -1;
}
public BigInteger(float value)
: this((double)value)
{
}
public BigInteger(double value)
{
if (double.IsInfinity(value))
throw new OverflowException();
if (double.IsNaN(value))
throw new OverflowException();
byte[] bytes = BitConverter.GetBytes(value);
ulong num = Mantissa(bytes);
if (num == 0L)
{
int num2 = Exponent(bytes);
if (num2 == 0)
{
this._sign = 0;
this._data = zeroArray;
this._length = 0;
return;
}
BigInteger x = IsNegative(bytes) ? Negate(One) : One;
x = LeftShift(x, num2 - 0x3ff);
this._sign = x._sign;
this._data = x._data;
}
else
{
int num3 = Exponent(bytes);
num |= (ulong)0x10000000000000L;
BigInteger integer2 = new BigInteger(num);
integer2 = (num3 > 0x433) ? LeftShift(integer2, num3 - 0x433) : RightShift(integer2, 0x433 - num3);
this._sign = IsNegative(bytes) ? ((short)(integer2._sign * -1)) : integer2._sign;
this._data = integer2._data;
}
this._length = -1;
}
public BigInteger(decimal value)
{
int[] bits = decimal.GetBits(decimal.Truncate(value));
int num = 3;
while ((num > 0) && (bits[num - 1] == 0))
{
num--;
}
this._length = num;
if (num == 0)
{
this._sign = 0;
this._data = new uint[0];
}
else
{
uint[] numArray2 = new uint[num];
numArray2[0] = (uint)bits[0];
if (num > 1)
{
numArray2[1] = (uint)bits[1];
}
if (num > 2)
{
numArray2[2] = (uint)bits[2];
}
this._sign = ((bits[3] & -2147483648) != 0) ? ((short)(-1)) : ((short)1);
this._data = numArray2;
}
}
public BigInteger(byte[] value)
: this(value, false)
{
}
public BigInteger(byte[] value, bool negative)
{
if (value == null)
throw new ArgumentNullException("value");
int index = value.Length / 4;
int num2 = value.Length % 4;
if (num2 > 0)
{
this._data = new uint[index + 1];
}
else
{
this._data = new uint[index];
}
Buffer.BlockCopy(value, 0, this._data, 0, index * 4);
if (num2 > 0)
{
uint num3 = 0;
for (int i = 0; i < num2; i++)
{
num3 |= (uint)(value[(index * 4) + i] << (8 * i));
}
this._data[index] = num3;
}
this._sign = negative ? ((short)(-1)) : ((short)1);
this._length = -1;
if (this.Length == 0)
{
this._sign = 0;
this._data = zeroArray;
}
}
private BigInteger(int _sign, params uint[] _data)
{
if (GetLength(_data) == 0)
{
_sign = 0;
}
this._data = _data;
this._sign = (short)_sign;
this._length = -1;
}
#endregion
#region Static Properties
public static BigInteger Zero
{
get
{
return new BigInteger(0, zeroArray);
}
}
public static BigInteger One
{
get
{
return new BigInteger(1);
}
}
public static BigInteger MinusOne
{
get
{
return new BigInteger(-1);
}
}
#endregion
#region Static Methods
public static BigInteger Abs(BigInteger x)
{
if (x._sign == -1)
{
return -x;
}
return x;
}
public static BigInteger GreatestCommonDivisor(BigInteger x, BigInteger y)
{
BigInteger integer;
BigInteger integer2;
if (x.Sign == 0)
throw new ArgumentOutOfRangeException("x", "Must Be Positive");
if (y.Sign == 0)
throw new ArgumentOutOfRangeException("y", "MustBePositive");
x = Abs(x);
y = Abs(y);
int num = Compare(x, y);
if (num == 0)
{
return x;
}
if (num < 1)
{
integer = x;
integer2 = y;
}
else
{
integer = y;
integer2 = x;
}
do
{
BigInteger integer3;
BigInteger integer4 = integer2;
DivRem(integer, integer2, out integer3);
integer2 = integer3;
integer = integer4;
}
while (integer2 != 0);
return integer;
}
public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
{
BigInteger integer;
DivRem(dividend, divisor, out integer);
return integer;
}
public static BigInteger Negate(BigInteger x)
{
BigInteger integer = new BigInteger(-x._sign, (x._data == null) ? zeroArray : x._data);
integer._length = x._length;
return integer;
}
public static BigInteger Pow(BigInteger baseValue, BigInteger exponent)
{
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
if (exponent == 0)
{
return One;
}
BigInteger integer = baseValue;
BigInteger result = One;
while (exponent > 0)
{
if ((exponent._data[0] & 1) != 0)
{
result *= integer;
}
if (exponent == 1)
{
return result;
}
integer = integer.Square();
exponent = RightShift(exponent, 1);
}
return result;
}
public static BigInteger ModPow(BigInteger baseValue, BigInteger exponent, BigInteger modulus)
{
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
if (exponent == 0)
{
return One;
}
BigInteger integer = baseValue;
BigInteger result = One;
while (exponent > 0)
{
if ((exponent._data[0] & 1) != 0)
{
result *= integer;
result = result % modulus;
}
if (exponent == 1)
{
return result;
}
integer = integer.Square();
exponent = RightShift(exponent, 1);
}
return result;
}
private static bool IsNegative(byte[] doubleBits)
{
return ((doubleBits[7] & 0x80) != 0);
}
private static ushort Exponent(byte[] doubleBits)
{
return (ushort)((((ushort)(doubleBits[7] & 0x7f)) << 4) | (((ushort)(doubleBits[6] & 240)) >> 4));
}
private static ulong Mantissa(byte[] doubleBits)
{
uint num = (uint)(((doubleBits[0] | (doubleBits[1] << 8)) | (doubleBits[2] << 0x10)) | (doubleBits[3] << 0x18));
uint num2 = (uint)((doubleBits[4] | (doubleBits[5] << 8)) | ((doubleBits[6] & 15) << 0x10));
return (num | (num2 << 0x20));
}
private static int GetLength(uint[] _data)
{
if (_data == null)
{
return 0;
}
int index = _data.Length - 1;
while ((index >= 0) && (_data[index] == 0))
{
index--;
}
return (index + 1);
}
private static uint[] copy(uint[] v)
{
uint[] destinationArray = new uint[v.Length];
Array.Copy(v, destinationArray, v.Length);
return destinationArray;
}
private static uint[] resize(uint[] v, int len)
{
if (v.Length == len)
{
return v;
}
uint[] destinationArray = new uint[len];
int length = Math.Min(v.Length, len);
Array.Copy(v, destinationArray, length);
return destinationArray;
}
private static uint[] add0(uint[] x, int xl, uint[] y, int yl)
{
if (xl >= yl)
{
return InternalAdd(x, xl, y, yl);
}
return InternalAdd(y, yl, x, xl);
}
private static uint[] InternalAdd(uint[] x, int xl, uint[] y, int yl)
{
uint[] result = new uint[xl];
ulong temp = 0L;
int index = 0;
while (index < yl)
{
temp = temp + x[index] + y[index];
result[index] = (uint)temp;
temp = temp >> 0x20;
index++;
}
while ((index < xl) && (temp != 0L))
{
temp += x[index];
result[index] = (uint)temp;
temp = temp >> 0x20;
index++;
}
if (temp == 0L)
{
while (index < xl)
{
result[index] = x[index];
index++;
}
return result;
}
result = resize(result, xl + 1);
result[index] = (uint)temp;
return result;
}
private static uint[] sub(uint[] x, int xl, uint[] y, int yl)
{
uint[] result = new uint[xl];
bool flag = false;
int index = 0;
while (index < yl)
{
uint currentX = x[index];
uint currentY = y[index];
if (flag)
{
if (currentX == 0)
{
currentX = uint.MaxValue;
flag = true;
}
else
{
currentX--;
flag = false;
}
}
if (currentY > currentX)
{
flag = true;
}
result[index] = currentX - currentY;
index++;
}
if (flag)
{
while (index < xl)
{
uint currentX = x[index];
result[index] = currentX - 1;
if (currentX != 0)
{
index++;
break;
}
index++;
}
}
while (index < xl)
{
result[index] = x[index];
index++;
}
return result;
}
public static int Compare(BigInteger x, BigInteger y)
{
if (x._sign == y._sign)
{
int xLength = x.Length;
int yLength = y.Length;
if (xLength == yLength)
{
for (int i = xLength - 1; i >= 0; i--)
{
if (x._data[i] != y._data[i])
{
if (x._data[i] <= y._data[i])
{
return -x._sign;
}
return x._sign;
}
}
return 0;
}
if (xLength <= yLength)
{
return -x._sign;
}
return x._sign;
}
if (x._sign <= y._sign)
{
return -1;
}
return 1;
}
public static BigInteger Add(BigInteger x, BigInteger y)
{
return x + y;
}
public static BigInteger Subtract(BigInteger x, BigInteger y)
{
return x - y;
}
public static BigInteger Multiply(BigInteger x, BigInteger y)
{
int xLength = x.Length;
int yLength = y.Length;
if (xLength + yLength >= 0x40 && xLength >= 8 && yLength >= 8)
{
return MultiplyKaratsuba(x, y);
}
return MultiplySchoolBook(x, y);
}
private static BigInteger MultiplySchoolBook(BigInteger x, BigInteger y)
{
int xLength = x.Length;
int yLength = y.Length;
int xyLength = xLength + yLength;
uint[] xData = x._data;
uint[] yData = y._data;
uint[] xyData = new uint[xyLength];
for (int i = 0; i < xLength; i++)
{
uint xNum = xData[i];
int index = i;
ulong temp = 0L;
for (int j = 0; j < yLength; j++)
{
temp = (temp + ((ulong)xNum * yData[j])) + xyData[index];
xyData[index++] = (uint)temp;
temp = temp >> 0x20;
}
while (temp != 0L)
{
temp += xyData[index];
xyData[index++] = (uint)temp;
temp = temp >> 0x20;
}
}
return new BigInteger(x._sign * y._sign, xyData);
}
private static BigInteger MultiplyKaratsuba(BigInteger x, BigInteger y)
{
int halfLength = Math.Max(x.Length, y.Length) / 2;
if (((halfLength <= 0x10) || (x.Length < 0x10)) || (y.Length < 0x10))
{
return MultiplySchoolBook(x, y);
}
int shift = 0x20 * halfLength;
BigInteger int1 = RightShift(x, shift);
BigInteger int2 = x.RestrictTo(halfLength);
BigInteger int3 = RightShift(y, shift);
BigInteger int4 = y.RestrictTo(halfLength);
BigInteger int5 = Multiply(int1, int3);
BigInteger int6 = Multiply(int2, int4);
BigInteger int7 = Multiply(int1 + int2, int3 + int4) - (int5 + int6);
return (int6 + LeftShift(int7 + LeftShift(int5, shift), shift));
}
public static BigInteger Divide(BigInteger dividend, BigInteger divisor)
{
return dividend / divisor;
}
private static int GetNormalizeShift(uint value)
{
int num = 0;
if ((value & 0xffff0000) == 0)
{
value = value << 0x10;
num += 0x10;
}
if ((value & 0xff000000) == 0)
{
value = value << 8;
num += 8;
}
if ((value & 0xf0000000) == 0)
{
value = value << 4;
num += 4;
}
if ((value & 0xc0000000) == 0)
{
value = value << 2;
num += 2;
}
if ((value & 0x80000000) == 0)
{
value = value << 1;
num++;
}
return num;
}
private static void Normalize(uint[] u, int l, uint[] un, int shift)
{
int index;
uint temp = 0;
if (shift > 0)
{
int sh = 0x20 - shift;
for (index = 0; index < l; index++)
{
uint current = u[index];
un[index] = (current << shift) | temp;
temp = current >> sh;
}
}
else
{
index = 0;
while (index < l)
{
un[index] = u[index];
index++;
}
}
while (index < un.Length)
{
un[index++] = 0;
}
if (temp != 0)
{
un[l] = temp;
}
}
private static void Unnormalize(uint[] un, out uint[] r, int shift)
{
int length = GetLength(un);
r = new uint[length];
if (shift > 0)
{
int sh = 0x20 - shift;
uint temp = 0;
for (int i = length - 1; i >= 0; i--)
{
uint current = un[i];
r[i] = (current >> shift) | temp;
temp = current << sh;
}
}
else
{
for (int j = 0; j < length; j++)
{
r[j] = un[j];
}
}
}
private static void DivModUnsigned(uint[] u, uint[] v, out uint[] q, out uint[] r)
{
int uLength = GetLength(u);
int vLength = GetLength(v);
if (vLength <= 1)
{
if (vLength == 0)
{
throw new DivideByZeroException();
}
ulong temp = 0L;
uint vCurrent = v[0];
q = new uint[uLength];
r = new uint[1];
for (int i = uLength - 1; i >= 0; i--)
{
temp *= (ulong)0x100000000L;
temp += u[i];
ulong temp2 = temp / ((ulong)vCurrent);
temp -= temp2 * vCurrent;
q[i] = (uint)temp2;
}
r[0] = (uint)temp;
}
else if (uLength >= vLength)
{
int normalizeShift = GetNormalizeShift(v[vLength - 1]);
uint[] un = new uint[uLength + 1];
uint[] vArray = new uint[vLength];
Normalize(u, uLength, un, normalizeShift);
Normalize(v, vLength, vArray, normalizeShift);
q = new uint[(uLength - vLength) + 1];
r = null;
for (int i = uLength - vLength; i >= 0; i--)
{
ulong temp = (ulong)((0x100000000L * un[i + vLength]) + un[(i + vLength) - 1]);
ulong current = temp / ((ulong)vArray[vLength - 1]);
temp -= current * vArray[vLength - 1];
do
{
if ((current < 0x100000000L) && ((current * vArray[vLength - 2]) <= ((temp * ((ulong)0x100000000L)) + un[(i + vLength) - 2])))
{
break;
}
current -= (ulong)1L;
temp += vArray[vLength - 1];
}
while (temp < 0x100000000L);
long temp2 = 0L;
long temp3 = 0L;
int index = 0;
while (index < vLength)
{
ulong temp4 = vArray[index] * current;
temp3 = (un[index + i] - ((uint)temp4)) - temp2;
un[index + i] = (uint)temp3;
temp4 = temp4 >> 0x20;
temp3 = temp3 >> 0x20;
temp2 = ((long)temp4) - temp3;
index++;
}
temp3 = un[i + vLength] - temp2;
un[i + vLength] = (uint)temp3;
q[i] = (uint)current;
if (temp3 < 0L)
{
q[i]--;
ulong num15 = 0L;
for (index = 0; index < vLength; index++)
{
num15 = (vArray[index] + un[i + index]) + num15;
un[i + index] = (uint)num15;
num15 = num15 >> 0x20;
}
num15 += un[i + vLength];
un[i + vLength] = (uint)num15;
}
}
Unnormalize(un, out r, normalizeShift);
}
else
{
q = zeroArray;
r = u;
}
}
public static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder)
{
uint[] q;
uint[] r;
DivModUnsigned((dividend._data == null) ? zeroArray : dividend._data, (divisor._data == null) ? zeroArray : divisor._data, out q, out r);
remainder = new BigInteger(dividend._sign, r);
return new BigInteger(dividend._sign * divisor._sign, q);
}
private static BigInteger LeftShift(BigInteger x, int shift)
{
if (shift == 0)
{
return x;
}
if (shift < 0)
{
return RightShift(x, -shift);
}
int sh = shift / 0x20;
int sh2 = shift - (sh * 0x20);
int xLength = x.Length;
uint[] xData = x._data;
int newLength = (xLength + sh) + 1;
uint[] newArray = new uint[newLength];
if (sh2 == 0)
{
for (int i = 0; i < xLength; i++)
{
newArray[i + sh] = xData[i];
}
}
else
{
int sh3 = 0x20 - sh2;
uint temp = 0;
int index = 0;
while (index < xLength)
{
uint current = xData[index];
newArray[index + sh] = (current << sh2) | temp;
temp = current >> sh3;
index++;
}
newArray[index + sh] = temp;
}
return new BigInteger(x._sign, newArray);
}
private static BigInteger RightShift(BigInteger x, int shift)
{
if (shift == 0)
{
return x;
}
if (shift < 0)
{
return LeftShift(x, -shift);
}
int sh = shift / 0x20;
int sh2 = shift - (sh * 0x20);
int xLength = x.Length;
uint[] xData = x._data;
int newLength = xLength - sh;
if (newLength < 0)
{
newLength = 0;
}
uint[] newArray = new uint[newLength];
if (sh2 == 0)
{
for (int i = xLength - 1; i >= sh; i--)
{
newArray[i - sh] = xData[i];
}
}
else
{
int sh3 = 0x20 - sh2;
uint temp = 0;
for (int j = xLength - 1; j >= sh; j--)
{
uint current = xData[j];
newArray[j - sh] = (current >> sh2) | temp;
temp = current << sh3;
}
}
return new BigInteger(x._sign, newArray);
}
public static BigInteger Parse(string s)
{
return Parse(s, CultureInfo.CurrentCulture);
}
public static BigInteger Parse(string s, IFormatProvider provider)
{
return Parse(s, NumberStyles.Integer, provider);
}
public static BigInteger Parse(string s, NumberStyles style)
{
return Parse(s, style, CultureInfo.CurrentCulture);
}
public static BigInteger Parse(string s, NumberStyles style, IFormatProvider provider)
{
BigInteger integer;
string str;
if (!TryParse(s, style, provider, out integer, out str))
{
throw new FormatException(str);
}
return integer;
}
public static bool TryParse(string s, out BigInteger b)
{
string str;
return TryParse(s, NumberStyles.Integer, CultureInfo.CurrentCulture, out b, out str);
}
public static bool TryParse(string s, NumberStyles style, IFormatProvider formatProvider, out BigInteger value)
{
string str;
return TryParse(s, style, formatProvider, out value, out str);
}
private static bool TryParse(string s, NumberStyles style, IFormatProvider formatProvider, out BigInteger value, out string error)
{
if (formatProvider == null)
{
formatProvider = CultureInfo.CurrentCulture;
}
if ((style & ~(NumberStyles.HexNumber | NumberStyles.AllowLeadingSign)) != NumberStyles.None)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentUICulture, "Unsupported Number Style {0}", new object[] { style }));
}
error = null;
NumberFormatInfo format = (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo));
uint radix = (uint)(((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) ? 0x10 : 10);
int index = 0;
bool flag = false;
if ((style & NumberStyles.AllowLeadingWhite) != NumberStyles.None)
{
while ((index < s.Length) && IsWhiteSpace(s[index]))
{
index++;
}
}
if ((style & NumberStyles.AllowLeadingSign) != NumberStyles.None)
{
int length = format.NegativeSign.Length;
if (((length + index) < s.Length) && (string.Compare(s, index, format.NegativeSign, 0, length, false, CultureInfo.CurrentCulture) == 0))
{
flag = true;
index += format.NegativeSign.Length;
}
}
value = Zero;
BigInteger rate = One;
if (index == s.Length)
{
error = "ParsedStringWasInvalid";
return false;
}
for (int i = s.Length - 1; i >= index; i--)
{
if (((style & NumberStyles.AllowTrailingWhite) != NumberStyles.None) && IsWhiteSpace(s[i]))
{
int currentIndex = i;
while (currentIndex >= index)
{
if (!IsWhiteSpace(s[currentIndex]))
{
break;
}
currentIndex--;
}
if (currentIndex < index)
{
error = "ParsedStringWasInvalid";
return false;
}
i = currentIndex;
}
uint singleDigit = ParseSingleDigit(s[i], (ulong)radix, out error);
if (error != null)
{
return false;
}
if (singleDigit != 0)
{
value += singleDigit * rate;
}
rate *= radix;
}
if ((value._sign == 1) && flag)
{
value = -value;
}
return true;
}
private static uint ParseSingleDigit(char c, ulong radix, out string error)
{
error = null;
if ((c >= '0') && (c <= '9'))
{
return (uint)(c - '0');
}
if (radix == 0x10L)
{
c = (char)(c & '');
if ((c >= 'A') && (c <= 'F'))
{
return (uint)((c - 'A') + 10);
}
}
error = "InvalidCharactersInString";
return uint.MaxValue;
}
private static bool IsWhiteSpace(char ch)
{
return ((ch == ' ') || ((ch >= '/t') && (ch <= '/r')));
}
private static void AppendRadix(uint rem, uint radix, bool useCapitalHexDigits, char[] tmp, StringBuilder buf, bool leadingZeros)
{
string str = useCapitalHexDigits ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "0123456789abcdefghijklmnopqrstuvwxyz";
int length = tmp.Length;
int startIndex = length;
while ((startIndex > 0) && (leadingZeros || (rem != 0)))
{
uint index = rem % radix;
rem /= radix;
tmp[--startIndex] = str[(int)index];
}
if (leadingZeros)
{
buf.Append(tmp);
}
else
{
buf.Append(tmp, startIndex, length - startIndex);
}
}
private static uint div(uint[] n, ref int nl, uint d)
{
ulong num = 0L;
int index = nl;
bool flag = false;
while (--index >= 0)
{
num = num << 0x20;
num |= n[index];
uint num3 = (uint)(num / ((ulong)d));
n[index] = num3;
if (num3 == 0)
{
if (!flag)
{
nl--;
}
}
else
{
flag = true;
}
num = num % ((ulong)d);
}
return (uint)num;
}
#endregion
#region Operators
public static BigInteger operator +(BigInteger value)
{
return value;
}
public static BigInteger operator -(BigInteger value)
{
return Negate(value);
}
public static BigInteger operator ++(BigInteger value)
{
if (value._sign >= 0)
{
return new BigInteger(1, add0(value._data, value.Length, new uint[] { 1 }, 1));
}
if ((value.Length == 1) && (value._data[0] == 1))
{
return Zero;
}
return new BigInteger(-1, sub(value._data, value.Length, new uint[] { 1 }, 1));
}
public static BigInteger operator --(BigInteger value)
{
uint[] numArray;
int num;
int length = value.Length;
if (value._sign == 1)
{
if ((length == 1) && (value._data[0] == 1))
{
return Zero;
}
numArray = sub(value._data, length, new uint[] { 1 }, 1);
num = 1;
}
else
{
numArray = add0(value._data, length, new uint[] { 1 }, 1);
num = -1;
}
return new BigInteger(num, numArray);
}
public static BigInteger operator +(BigInteger x, BigInteger y)
{
if (x._sign == y._sign)
{
return new BigInteger(x._sign, add0(x._data, x.Length, y._data, y.Length));
}
return (x - (-y));
}
public static BigInteger operator -(BigInteger x, BigInteger y)
{
uint[] array;
int compare = Compare(x, y);
if (compare != 0)
{
if (x._sign != y._sign)
{
return new BigInteger(compare, add0(x._data, x.Length, y._data, y.Length));
}
switch ((compare * x._sign))
{
case -1:
array = sub(y._data, y.Length, x._data, x.Length);
return new BigInteger(compare, array);
case 1:
array = sub(x._data, x.Length, y._data, y.Length);
return new BigInteger(compare, array);
default:
break;
}
}
return Zero;
}
public static BigInteger operator *(BigInteger x, BigInteger y)
{
return Multiply(x, y);
}
public static BigInteger operator %(BigInteger x, BigInteger y)
{
BigInteger result;
if ((x._sign == y._sign) && (x.Length < y.Length))
{
return x;
}
DivRem(x, y, out result);
return result;
}
public static BigInteger operator /(BigInteger dividend, BigInteger divisor)
{
BigInteger integer;
return DivRem(dividend, divisor, out integer);
}
public static bool operator ==(BigInteger x, BigInteger y)
{
return (Compare(x, y) == 0);
}
public static bool operator !=(BigInteger x, BigInteger y)
{
return (Compare(x, y) != 0);
}
public static bool operator <(BigInteger x, BigInteger y)
{
return (Compare(x, y) < 0);
}
public static bool operator <=(BigInteger x, BigInteger y)
{
return (Compare(x, y) <= 0);
}
public static bool operator >(BigInteger x, BigInteger y)
{
return (Compare(x, y) > 0);
}
public static bool operator >=(BigInteger x, BigInteger y)
{
return (Compare(x, y) >= 0);
}
public static explicit operator byte(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow Byte");
}
if (value._data[0] > 0xff)
{
throw new OverflowException("Overflow Byte");
}
if (value._sign < 0)
{
throw new OverflowException("Overflow Byte");
}
return (byte)value._data[0];
}
[CLSCompliant(false)]
public static explicit operator sbyte(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow sbyte");
}
if (value._data[0] > 0x80)
{
throw new OverflowException("Overflow sbyte");
}
if ((value._data[0] == 0x80) && (value._sign == 1))
{
throw new OverflowException("Overflow sbyte");
}
sbyte num = (sbyte)value._data[0];
return (sbyte)(num * ((sbyte)value._sign));
}
public static explicit operator short(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow int16");
}
if (value._data[0] > 0x8000)
{
throw new OverflowException("Overflow int16");
}
if ((value._data[0] == 0x8000) && (value._sign == 1))
{
throw new OverflowException("Overflow int16");
}
short num = (short)value._data[0];
return (short)(num * value._sign);
}
[CLSCompliant(false)]
public static explicit operator ushort(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow uint16");
}
if (value._data[0] > 0xffff)
{
throw new OverflowException("Overflow uint16");
}
if (value._sign < 0)
{
throw new OverflowException("Overflow uint16");
}
return (ushort)value._data[0];
}
public static explicit operator int(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow int32");
}
if (value._data[0] > 0x80000000)
{
throw new OverflowException("Overflow int32");
}
if ((value._data[0] == 0x80000000) && (value._sign == 1))
{
throw new OverflowException("Overflow int32");
}
int num = (int)value._data[0];
return (num * value._sign);
}
[CLSCompliant(false)]
public static explicit operator uint(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow uint32");
}
if (value._sign < 0)
{
throw new OverflowException("Overflow uint32");
}
return value._data[0];
}
public static explicit operator long(BigInteger value)
{
if (value._sign == 0)
{
return 0L;
}
if (value.Length > 2)
{
throw new OverflowException("Overflow int64");
}
if (value.Length == 1)
{
return (value._sign * value._data[0]);
}
ulong num2 = (value._data[1] << 0x20) | value._data[0];
if (num2 > 9223372036854775808L)
{
throw new OverflowException("Overflow int64");
}
if ((num2 == 9223372036854775808L) && (value._sign == 1))
{
throw new OverflowException("Overflow int64");
}
return (long)num2 * (long)value._sign;
}
[CLSCompliant(false)]
public static explicit operator ulong(BigInteger value)
{
ulong num = 0L;
if (value._sign == 0)
{
return 0L;
}
if (value._sign < 0)
{
throw new OverflowException("Overflow uint64");
}
if (value.Length > 2)
{
throw new OverflowException("Overflow uint64");
}
num = value._data[0];
if (value.Length > 1)
{
num |= value._data[1] << 0x20;
}
return num;
}
public static explicit operator float(BigInteger value)
{
float num;
NumberFormatInfo numberFormat = CultureInfo.InvariantCulture.NumberFormat;
if (!float.TryParse(value.ToString(10, false, numberFormat), NumberStyles.Number, (IFormatProvider)numberFormat, out num))
{
throw new OverflowException("Overflow single");
}
return num;
}
public static explicit operator double(BigInteger value)
{
double num;
NumberFormatInfo numberFormat = CultureInfo.InvariantCulture.NumberFormat;
if (!double.TryParse(value.ToString(10, false, numberFormat), NumberStyles.Number, (IFormatProvider)numberFormat, out num))
{
throw new OverflowException("Overflow double");
}
return num;
}
public static explicit operator decimal(BigInteger value)
{
if (value._sign == 0)
{
return 0M;
}
int length = value.Length;
if (length > 3)
{
throw new OverflowException("Overflow Decimal");
}
int lo = 0;
int mid = 0;
int hi = 0;
if (length > 2)
{
hi = (int)value._data[2];
}
if (length > 1)
{
mid = (int)value._data[1];
}
if (length > 0)
{
lo = (int)value._data[0];
}
return new decimal(lo, mid, hi, value._sign < 0, 0);
}
public static explicit operator BigInteger(float value)
{
return new BigInteger(value);
}
public static explicit operator BigInteger(double value)
{
return new BigInteger(value);
}
public static explicit operator BigInteger(decimal value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(byte value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(sbyte value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(short value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(ushort value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(int value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(uint value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(long value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(ulong value)
{
return new BigInteger(value);
}
#endregion
#region Instance Properties
public int Sign
{
get
{
return this._sign;
}
}
private int Length
{
get
{
if (this._length == -1)
{
this._length = GetLength(this._data);
}
return this._length;
}
}
#endregion
#region Instance Methods
private BigInteger Square()
{
return (this * this);
}
public byte[] ToByteArray()
{
bool flag;
return this.ToByteArray(out flag);
}
public byte[] ToByteArray(out bool isNegative)
{
int length = this.Length;
byte[] result = new byte[length * 4];
Buffer.BlockCopy(this._data, 0, result, 0, length * 4);
isNegative = this._sign == -1;
return result;
}
private BigInteger RestrictTo(int numDigits)
{
int length = Math.Min(numDigits, this.Length);
if (length == this.Length)
{
return this;
}
BigInteger result = new BigInteger(this._sign, this._data);
result._length = length;
return result;
}
public string ToString(string format)
{
return this.ToString(format, CultureInfo.CurrentCulture);
}
public string ToString(IFormatProvider formatProvider)
{
if (formatProvider == null)
{
formatProvider = CultureInfo.CurrentCulture;
}
return this.ToString(10, false, (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo)));
}
public string ToString(string format, IFormatProvider formatProvider)
{
if (formatProvider == null)
{
formatProvider = CultureInfo.CurrentCulture;
}
uint radix = 10;
bool useCapitalHexDigits = false;
if (!string.IsNullOrEmpty(format))
{
char ch = format[0];
switch (ch)
{
case 'X':
case 'x':
radix = 0x10;
useCapitalHexDigits = ch == 'X';
break;
default:
if (((ch != 'G') && (ch != 'g')) && ((ch != 'D') && (ch != 'd')))
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Currently not supported format: {0}", new object[] { format }));
}
break;
}
}
return this.ToString(radix, useCapitalHexDigits, (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo)));
}
public override string ToString()
{
return this.ToString(10, false, CultureInfo.CurrentCulture.NumberFormat);
}
private string ToString(uint radix, bool useCapitalHexDigits, NumberFormatInfo info)
{
if (this._sign == 0)
{
return "0";
}
int length = this.Length;
List<uint> list = new List<uint>();
uint[] n = copy(this._data);
int nl = this.Length;
uint d = groupRadixValues[radix];
while (nl > 0)
{
uint item = div(n, ref nl, d);
list.Add(item);
}
StringBuilder sb = new StringBuilder();
if (this._sign == -1)
{
sb.Append(info.NegativeSign);
}
int index = list.Count - 1;
char[] tmp = new char[maxCharsPerDigit[radix]];
AppendRadix(list[index--], radix, useCapitalHexDigits, tmp, sb, false);
while (index >= 0)
{
AppendRadix(list[index--], radix, useCapitalHexDigits, tmp, sb, true);
}
return sb.ToString();
}
public override int GetHashCode()
{
if (this._sign == 0)
{
return 0;
}
return (int)this._data[0];
}
public bool Equals(BigInteger other)
{
if (this._sign != other._sign)
{
return false;
}
int length = this.Length;
int otherLength = other.Length;
if (length != otherLength)
{
return false;
}
for (uint i = 0; i < length; i++)
{
if (this._data[i] != other._data[i])
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return (((obj != null) && (obj is BigInteger)) && this.Equals((BigInteger)obj));
}
public int CompareTo(BigInteger other)
{
return Compare(this, other);
}
public int CompareTo(object obj)
{
if (obj == null)
{
return 1;
}
if (!(obj is BigInteger))
{
throw new ArgumentException("MustBeBigInt");
}
return Compare(this, (BigInteger)obj);
}
#endregion
}
public struct BigInteger : IFormattable, IEquatable<BigInteger>, IComparable<BigInteger>, IComparable
{
#region Fields
private const int DecimalScaleFactorMask = 0xff0000;
private const int DecimalSignMask = -2147483648;
private const int BitsPerDigit = 0x20;
private const ulong Base = 0x100000000L;
private const int UpperBoundForSchoolBookMultiplicationDigits = 0x40;
private const int ForceSchoolBookMultiplicationThresholdDigits = 8;
private static readonly uint[] maxCharsPerDigit;
private static readonly uint[] groupRadixValues;
private static readonly uint[] zeroArray;
private readonly short _sign;
private readonly uint[] _data;
private int _length;
#endregion
#region Ctors
static BigInteger()
{
maxCharsPerDigit = new uint[]
{
0, 0, 0x1f, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, 8, 8,
7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6
};
groupRadixValues = new uint[]
{
0, 0, 0x80000000, 0xcfd41b91, 0x40000000, 0x48c27395, 0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91, 0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021, 0x57f6c100, 0x98c29b81,
0x10000000, 0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d, 0x94ace180, 0xcaf18367, 0xb640000, 0xe8d4a51, 0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41,
0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x81bf1000
};
zeroArray = new uint[0];
}
public BigInteger(int value)
{
if (value == 0)
{
this._sign = 0;
this._data = new uint[0];
}
else if (value < 0)
{
this._sign = -1;
this._data = new uint[] { (uint)-value };
}
else
{
this._sign = 1;
this._data = new uint[] { (uint)value };
}
this._length = -1;
}
public BigInteger(long value)
{
ulong num = 0L;
if (value < 0L)
{
num = (ulong)-value;
this._sign = -1;
}
else if (value > 0L)
{
num = (ulong)value;
this._sign = 1;
}
else
{
this._sign = 0;
}
if (num >= 0x100000000L)
{
this._data = new uint[] { (uint)num, (uint)(num >> 0x20) };
}
else
{
this._data = new uint[] { (uint)num };
}
this._length = -1;
}
[CLSCompliant(false)]
public BigInteger(uint value)
{
if (value == 0)
{
this._sign = 0;
}
else
{
this._sign = 1;
}
this._data = new uint[] { value };
this._length = -1;
}
[CLSCompliant(false)]
public BigInteger(ulong value)
{
if (value == 0L)
{
this._sign = 0;
}
else
{
this._sign = 1;
}
if (value >= 0x100000000L)
{
this._data = new uint[] { (uint)value, (uint)(value >> 0x20) };
}
else
{
this._data = new uint[] { (uint)value };
}
this._length = -1;
}
public BigInteger(float value)
: this((double)value)
{
}
public BigInteger(double value)
{
if (double.IsInfinity(value))
throw new OverflowException();
if (double.IsNaN(value))
throw new OverflowException();
byte[] bytes = BitConverter.GetBytes(value);
ulong num = Mantissa(bytes);
if (num == 0L)
{
int num2 = Exponent(bytes);
if (num2 == 0)
{
this._sign = 0;
this._data = zeroArray;
this._length = 0;
return;
}
BigInteger x = IsNegative(bytes) ? Negate(One) : One;
x = LeftShift(x, num2 - 0x3ff);
this._sign = x._sign;
this._data = x._data;
}
else
{
int num3 = Exponent(bytes);
num |= (ulong)0x10000000000000L;
BigInteger integer2 = new BigInteger(num);
integer2 = (num3 > 0x433) ? LeftShift(integer2, num3 - 0x433) : RightShift(integer2, 0x433 - num3);
this._sign = IsNegative(bytes) ? ((short)(integer2._sign * -1)) : integer2._sign;
this._data = integer2._data;
}
this._length = -1;
}
public BigInteger(decimal value)
{
int[] bits = decimal.GetBits(decimal.Truncate(value));
int num = 3;
while ((num > 0) && (bits[num - 1] == 0))
{
num--;
}
this._length = num;
if (num == 0)
{
this._sign = 0;
this._data = new uint[0];
}
else
{
uint[] numArray2 = new uint[num];
numArray2[0] = (uint)bits[0];
if (num > 1)
{
numArray2[1] = (uint)bits[1];
}
if (num > 2)
{
numArray2[2] = (uint)bits[2];
}
this._sign = ((bits[3] & -2147483648) != 0) ? ((short)(-1)) : ((short)1);
this._data = numArray2;
}
}
public BigInteger(byte[] value)
: this(value, false)
{
}
public BigInteger(byte[] value, bool negative)
{
if (value == null)
throw new ArgumentNullException("value");
int index = value.Length / 4;
int num2 = value.Length % 4;
if (num2 > 0)
{
this._data = new uint[index + 1];
}
else
{
this._data = new uint[index];
}
Buffer.BlockCopy(value, 0, this._data, 0, index * 4);
if (num2 > 0)
{
uint num3 = 0;
for (int i = 0; i < num2; i++)
{
num3 |= (uint)(value[(index * 4) + i] << (8 * i));
}
this._data[index] = num3;
}
this._sign = negative ? ((short)(-1)) : ((short)1);
this._length = -1;
if (this.Length == 0)
{
this._sign = 0;
this._data = zeroArray;
}
}
private BigInteger(int _sign, params uint[] _data)
{
if (GetLength(_data) == 0)
{
_sign = 0;
}
this._data = _data;
this._sign = (short)_sign;
this._length = -1;
}
#endregion
#region Static Properties
public static BigInteger Zero
{
get
{
return new BigInteger(0, zeroArray);
}
}
public static BigInteger One
{
get
{
return new BigInteger(1);
}
}
public static BigInteger MinusOne
{
get
{
return new BigInteger(-1);
}
}
#endregion
#region Static Methods
public static BigInteger Abs(BigInteger x)
{
if (x._sign == -1)
{
return -x;
}
return x;
}
public static BigInteger GreatestCommonDivisor(BigInteger x, BigInteger y)
{
BigInteger integer;
BigInteger integer2;
if (x.Sign == 0)
throw new ArgumentOutOfRangeException("x", "Must Be Positive");
if (y.Sign == 0)
throw new ArgumentOutOfRangeException("y", "MustBePositive");
x = Abs(x);
y = Abs(y);
int num = Compare(x, y);
if (num == 0)
{
return x;
}
if (num < 1)
{
integer = x;
integer2 = y;
}
else
{
integer = y;
integer2 = x;
}
do
{
BigInteger integer3;
BigInteger integer4 = integer2;
DivRem(integer, integer2, out integer3);
integer2 = integer3;
integer = integer4;
}
while (integer2 != 0);
return integer;
}
public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
{
BigInteger integer;
DivRem(dividend, divisor, out integer);
return integer;
}
public static BigInteger Negate(BigInteger x)
{
BigInteger integer = new BigInteger(-x._sign, (x._data == null) ? zeroArray : x._data);
integer._length = x._length;
return integer;
}
public static BigInteger Pow(BigInteger baseValue, BigInteger exponent)
{
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
if (exponent == 0)
{
return One;
}
BigInteger integer = baseValue;
BigInteger result = One;
while (exponent > 0)
{
if ((exponent._data[0] & 1) != 0)
{
result *= integer;
}
if (exponent == 1)
{
return result;
}
integer = integer.Square();
exponent = RightShift(exponent, 1);
}
return result;
}
public static BigInteger ModPow(BigInteger baseValue, BigInteger exponent, BigInteger modulus)
{
if (exponent < 0)
throw new ArgumentOutOfRangeException("exponent", "NonNegative");
if (exponent == 0)
{
return One;
}
BigInteger integer = baseValue;
BigInteger result = One;
while (exponent > 0)
{
if ((exponent._data[0] & 1) != 0)
{
result *= integer;
result = result % modulus;
}
if (exponent == 1)
{
return result;
}
integer = integer.Square();
exponent = RightShift(exponent, 1);
}
return result;
}
private static bool IsNegative(byte[] doubleBits)
{
return ((doubleBits[7] & 0x80) != 0);
}
private static ushort Exponent(byte[] doubleBits)
{
return (ushort)((((ushort)(doubleBits[7] & 0x7f)) << 4) | (((ushort)(doubleBits[6] & 240)) >> 4));
}
private static ulong Mantissa(byte[] doubleBits)
{
uint num = (uint)(((doubleBits[0] | (doubleBits[1] << 8)) | (doubleBits[2] << 0x10)) | (doubleBits[3] << 0x18));
uint num2 = (uint)((doubleBits[4] | (doubleBits[5] << 8)) | ((doubleBits[6] & 15) << 0x10));
return (num | (num2 << 0x20));
}
private static int GetLength(uint[] _data)
{
if (_data == null)
{
return 0;
}
int index = _data.Length - 1;
while ((index >= 0) && (_data[index] == 0))
{
index--;
}
return (index + 1);
}
private static uint[] copy(uint[] v)
{
uint[] destinationArray = new uint[v.Length];
Array.Copy(v, destinationArray, v.Length);
return destinationArray;
}
private static uint[] resize(uint[] v, int len)
{
if (v.Length == len)
{
return v;
}
uint[] destinationArray = new uint[len];
int length = Math.Min(v.Length, len);
Array.Copy(v, destinationArray, length);
return destinationArray;
}
private static uint[] add0(uint[] x, int xl, uint[] y, int yl)
{
if (xl >= yl)
{
return InternalAdd(x, xl, y, yl);
}
return InternalAdd(y, yl, x, xl);
}
private static uint[] InternalAdd(uint[] x, int xl, uint[] y, int yl)
{
uint[] result = new uint[xl];
ulong temp = 0L;
int index = 0;
while (index < yl)
{
temp = temp + x[index] + y[index];
result[index] = (uint)temp;
temp = temp >> 0x20;
index++;
}
while ((index < xl) && (temp != 0L))
{
temp += x[index];
result[index] = (uint)temp;
temp = temp >> 0x20;
index++;
}
if (temp == 0L)
{
while (index < xl)
{
result[index] = x[index];
index++;
}
return result;
}
result = resize(result, xl + 1);
result[index] = (uint)temp;
return result;
}
private static uint[] sub(uint[] x, int xl, uint[] y, int yl)
{
uint[] result = new uint[xl];
bool flag = false;
int index = 0;
while (index < yl)
{
uint currentX = x[index];
uint currentY = y[index];
if (flag)
{
if (currentX == 0)
{
currentX = uint.MaxValue;
flag = true;
}
else
{
currentX--;
flag = false;
}
}
if (currentY > currentX)
{
flag = true;
}
result[index] = currentX - currentY;
index++;
}
if (flag)
{
while (index < xl)
{
uint currentX = x[index];
result[index] = currentX - 1;
if (currentX != 0)
{
index++;
break;
}
index++;
}
}
while (index < xl)
{
result[index] = x[index];
index++;
}
return result;
}
public static int Compare(BigInteger x, BigInteger y)
{
if (x._sign == y._sign)
{
int xLength = x.Length;
int yLength = y.Length;
if (xLength == yLength)
{
for (int i = xLength - 1; i >= 0; i--)
{
if (x._data[i] != y._data[i])
{
if (x._data[i] <= y._data[i])
{
return -x._sign;
}
return x._sign;
}
}
return 0;
}
if (xLength <= yLength)
{
return -x._sign;
}
return x._sign;
}
if (x._sign <= y._sign)
{
return -1;
}
return 1;
}
public static BigInteger Add(BigInteger x, BigInteger y)
{
return x + y;
}
public static BigInteger Subtract(BigInteger x, BigInteger y)
{
return x - y;
}
public static BigInteger Multiply(BigInteger x, BigInteger y)
{
int xLength = x.Length;
int yLength = y.Length;
if (xLength + yLength >= 0x40 && xLength >= 8 && yLength >= 8)
{
return MultiplyKaratsuba(x, y);
}
return MultiplySchoolBook(x, y);
}
private static BigInteger MultiplySchoolBook(BigInteger x, BigInteger y)
{
int xLength = x.Length;
int yLength = y.Length;
int xyLength = xLength + yLength;
uint[] xData = x._data;
uint[] yData = y._data;
uint[] xyData = new uint[xyLength];
for (int i = 0; i < xLength; i++)
{
uint xNum = xData[i];
int index = i;
ulong temp = 0L;
for (int j = 0; j < yLength; j++)
{
temp = (temp + ((ulong)xNum * yData[j])) + xyData[index];
xyData[index++] = (uint)temp;
temp = temp >> 0x20;
}
while (temp != 0L)
{
temp += xyData[index];
xyData[index++] = (uint)temp;
temp = temp >> 0x20;
}
}
return new BigInteger(x._sign * y._sign, xyData);
}
private static BigInteger MultiplyKaratsuba(BigInteger x, BigInteger y)
{
int halfLength = Math.Max(x.Length, y.Length) / 2;
if (((halfLength <= 0x10) || (x.Length < 0x10)) || (y.Length < 0x10))
{
return MultiplySchoolBook(x, y);
}
int shift = 0x20 * halfLength;
BigInteger int1 = RightShift(x, shift);
BigInteger int2 = x.RestrictTo(halfLength);
BigInteger int3 = RightShift(y, shift);
BigInteger int4 = y.RestrictTo(halfLength);
BigInteger int5 = Multiply(int1, int3);
BigInteger int6 = Multiply(int2, int4);
BigInteger int7 = Multiply(int1 + int2, int3 + int4) - (int5 + int6);
return (int6 + LeftShift(int7 + LeftShift(int5, shift), shift));
}
public static BigInteger Divide(BigInteger dividend, BigInteger divisor)
{
return dividend / divisor;
}
private static int GetNormalizeShift(uint value)
{
int num = 0;
if ((value & 0xffff0000) == 0)
{
value = value << 0x10;
num += 0x10;
}
if ((value & 0xff000000) == 0)
{
value = value << 8;
num += 8;
}
if ((value & 0xf0000000) == 0)
{
value = value << 4;
num += 4;
}
if ((value & 0xc0000000) == 0)
{
value = value << 2;
num += 2;
}
if ((value & 0x80000000) == 0)
{
value = value << 1;
num++;
}
return num;
}
private static void Normalize(uint[] u, int l, uint[] un, int shift)
{
int index;
uint temp = 0;
if (shift > 0)
{
int sh = 0x20 - shift;
for (index = 0; index < l; index++)
{
uint current = u[index];
un[index] = (current << shift) | temp;
temp = current >> sh;
}
}
else
{
index = 0;
while (index < l)
{
un[index] = u[index];
index++;
}
}
while (index < un.Length)
{
un[index++] = 0;
}
if (temp != 0)
{
un[l] = temp;
}
}
private static void Unnormalize(uint[] un, out uint[] r, int shift)
{
int length = GetLength(un);
r = new uint[length];
if (shift > 0)
{
int sh = 0x20 - shift;
uint temp = 0;
for (int i = length - 1; i >= 0; i--)
{
uint current = un[i];
r[i] = (current >> shift) | temp;
temp = current << sh;
}
}
else
{
for (int j = 0; j < length; j++)
{
r[j] = un[j];
}
}
}
private static void DivModUnsigned(uint[] u, uint[] v, out uint[] q, out uint[] r)
{
int uLength = GetLength(u);
int vLength = GetLength(v);
if (vLength <= 1)
{
if (vLength == 0)
{
throw new DivideByZeroException();
}
ulong temp = 0L;
uint vCurrent = v[0];
q = new uint[uLength];
r = new uint[1];
for (int i = uLength - 1; i >= 0; i--)
{
temp *= (ulong)0x100000000L;
temp += u[i];
ulong temp2 = temp / ((ulong)vCurrent);
temp -= temp2 * vCurrent;
q[i] = (uint)temp2;
}
r[0] = (uint)temp;
}
else if (uLength >= vLength)
{
int normalizeShift = GetNormalizeShift(v[vLength - 1]);
uint[] un = new uint[uLength + 1];
uint[] vArray = new uint[vLength];
Normalize(u, uLength, un, normalizeShift);
Normalize(v, vLength, vArray, normalizeShift);
q = new uint[(uLength - vLength) + 1];
r = null;
for (int i = uLength - vLength; i >= 0; i--)
{
ulong temp = (ulong)((0x100000000L * un[i + vLength]) + un[(i + vLength) - 1]);
ulong current = temp / ((ulong)vArray[vLength - 1]);
temp -= current * vArray[vLength - 1];
do
{
if ((current < 0x100000000L) && ((current * vArray[vLength - 2]) <= ((temp * ((ulong)0x100000000L)) + un[(i + vLength) - 2])))
{
break;
}
current -= (ulong)1L;
temp += vArray[vLength - 1];
}
while (temp < 0x100000000L);
long temp2 = 0L;
long temp3 = 0L;
int index = 0;
while (index < vLength)
{
ulong temp4 = vArray[index] * current;
temp3 = (un[index + i] - ((uint)temp4)) - temp2;
un[index + i] = (uint)temp3;
temp4 = temp4 >> 0x20;
temp3 = temp3 >> 0x20;
temp2 = ((long)temp4) - temp3;
index++;
}
temp3 = un[i + vLength] - temp2;
un[i + vLength] = (uint)temp3;
q[i] = (uint)current;
if (temp3 < 0L)
{
q[i]--;
ulong num15 = 0L;
for (index = 0; index < vLength; index++)
{
num15 = (vArray[index] + un[i + index]) + num15;
un[i + index] = (uint)num15;
num15 = num15 >> 0x20;
}
num15 += un[i + vLength];
un[i + vLength] = (uint)num15;
}
}
Unnormalize(un, out r, normalizeShift);
}
else
{
q = zeroArray;
r = u;
}
}
public static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder)
{
uint[] q;
uint[] r;
DivModUnsigned((dividend._data == null) ? zeroArray : dividend._data, (divisor._data == null) ? zeroArray : divisor._data, out q, out r);
remainder = new BigInteger(dividend._sign, r);
return new BigInteger(dividend._sign * divisor._sign, q);
}
private static BigInteger LeftShift(BigInteger x, int shift)
{
if (shift == 0)
{
return x;
}
if (shift < 0)
{
return RightShift(x, -shift);
}
int sh = shift / 0x20;
int sh2 = shift - (sh * 0x20);
int xLength = x.Length;
uint[] xData = x._data;
int newLength = (xLength + sh) + 1;
uint[] newArray = new uint[newLength];
if (sh2 == 0)
{
for (int i = 0; i < xLength; i++)
{
newArray[i + sh] = xData[i];
}
}
else
{
int sh3 = 0x20 - sh2;
uint temp = 0;
int index = 0;
while (index < xLength)
{
uint current = xData[index];
newArray[index + sh] = (current << sh2) | temp;
temp = current >> sh3;
index++;
}
newArray[index + sh] = temp;
}
return new BigInteger(x._sign, newArray);
}
private static BigInteger RightShift(BigInteger x, int shift)
{
if (shift == 0)
{
return x;
}
if (shift < 0)
{
return LeftShift(x, -shift);
}
int sh = shift / 0x20;
int sh2 = shift - (sh * 0x20);
int xLength = x.Length;
uint[] xData = x._data;
int newLength = xLength - sh;
if (newLength < 0)
{
newLength = 0;
}
uint[] newArray = new uint[newLength];
if (sh2 == 0)
{
for (int i = xLength - 1; i >= sh; i--)
{
newArray[i - sh] = xData[i];
}
}
else
{
int sh3 = 0x20 - sh2;
uint temp = 0;
for (int j = xLength - 1; j >= sh; j--)
{
uint current = xData[j];
newArray[j - sh] = (current >> sh2) | temp;
temp = current << sh3;
}
}
return new BigInteger(x._sign, newArray);
}
public static BigInteger Parse(string s)
{
return Parse(s, CultureInfo.CurrentCulture);
}
public static BigInteger Parse(string s, IFormatProvider provider)
{
return Parse(s, NumberStyles.Integer, provider);
}
public static BigInteger Parse(string s, NumberStyles style)
{
return Parse(s, style, CultureInfo.CurrentCulture);
}
public static BigInteger Parse(string s, NumberStyles style, IFormatProvider provider)
{
BigInteger integer;
string str;
if (!TryParse(s, style, provider, out integer, out str))
{
throw new FormatException(str);
}
return integer;
}
public static bool TryParse(string s, out BigInteger b)
{
string str;
return TryParse(s, NumberStyles.Integer, CultureInfo.CurrentCulture, out b, out str);
}
public static bool TryParse(string s, NumberStyles style, IFormatProvider formatProvider, out BigInteger value)
{
string str;
return TryParse(s, style, formatProvider, out value, out str);
}
private static bool TryParse(string s, NumberStyles style, IFormatProvider formatProvider, out BigInteger value, out string error)
{
if (formatProvider == null)
{
formatProvider = CultureInfo.CurrentCulture;
}
if ((style & ~(NumberStyles.HexNumber | NumberStyles.AllowLeadingSign)) != NumberStyles.None)
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentUICulture, "Unsupported Number Style {0}", new object[] { style }));
}
error = null;
NumberFormatInfo format = (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo));
uint radix = (uint)(((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None) ? 0x10 : 10);
int index = 0;
bool flag = false;
if ((style & NumberStyles.AllowLeadingWhite) != NumberStyles.None)
{
while ((index < s.Length) && IsWhiteSpace(s[index]))
{
index++;
}
}
if ((style & NumberStyles.AllowLeadingSign) != NumberStyles.None)
{
int length = format.NegativeSign.Length;
if (((length + index) < s.Length) && (string.Compare(s, index, format.NegativeSign, 0, length, false, CultureInfo.CurrentCulture) == 0))
{
flag = true;
index += format.NegativeSign.Length;
}
}
value = Zero;
BigInteger rate = One;
if (index == s.Length)
{
error = "ParsedStringWasInvalid";
return false;
}
for (int i = s.Length - 1; i >= index; i--)
{
if (((style & NumberStyles.AllowTrailingWhite) != NumberStyles.None) && IsWhiteSpace(s[i]))
{
int currentIndex = i;
while (currentIndex >= index)
{
if (!IsWhiteSpace(s[currentIndex]))
{
break;
}
currentIndex--;
}
if (currentIndex < index)
{
error = "ParsedStringWasInvalid";
return false;
}
i = currentIndex;
}
uint singleDigit = ParseSingleDigit(s[i], (ulong)radix, out error);
if (error != null)
{
return false;
}
if (singleDigit != 0)
{
value += singleDigit * rate;
}
rate *= radix;
}
if ((value._sign == 1) && flag)
{
value = -value;
}
return true;
}
private static uint ParseSingleDigit(char c, ulong radix, out string error)
{
error = null;
if ((c >= '0') && (c <= '9'))
{
return (uint)(c - '0');
}
if (radix == 0x10L)
{
c = (char)(c & '');
if ((c >= 'A') && (c <= 'F'))
{
return (uint)((c - 'A') + 10);
}
}
error = "InvalidCharactersInString";
return uint.MaxValue;
}
private static bool IsWhiteSpace(char ch)
{
return ((ch == ' ') || ((ch >= '/t') && (ch <= '/r')));
}
private static void AppendRadix(uint rem, uint radix, bool useCapitalHexDigits, char[] tmp, StringBuilder buf, bool leadingZeros)
{
string str = useCapitalHexDigits ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "0123456789abcdefghijklmnopqrstuvwxyz";
int length = tmp.Length;
int startIndex = length;
while ((startIndex > 0) && (leadingZeros || (rem != 0)))
{
uint index = rem % radix;
rem /= radix;
tmp[--startIndex] = str[(int)index];
}
if (leadingZeros)
{
buf.Append(tmp);
}
else
{
buf.Append(tmp, startIndex, length - startIndex);
}
}
private static uint div(uint[] n, ref int nl, uint d)
{
ulong num = 0L;
int index = nl;
bool flag = false;
while (--index >= 0)
{
num = num << 0x20;
num |= n[index];
uint num3 = (uint)(num / ((ulong)d));
n[index] = num3;
if (num3 == 0)
{
if (!flag)
{
nl--;
}
}
else
{
flag = true;
}
num = num % ((ulong)d);
}
return (uint)num;
}
#endregion
#region Operators
public static BigInteger operator +(BigInteger value)
{
return value;
}
public static BigInteger operator -(BigInteger value)
{
return Negate(value);
}
public static BigInteger operator ++(BigInteger value)
{
if (value._sign >= 0)
{
return new BigInteger(1, add0(value._data, value.Length, new uint[] { 1 }, 1));
}
if ((value.Length == 1) && (value._data[0] == 1))
{
return Zero;
}
return new BigInteger(-1, sub(value._data, value.Length, new uint[] { 1 }, 1));
}
public static BigInteger operator --(BigInteger value)
{
uint[] numArray;
int num;
int length = value.Length;
if (value._sign == 1)
{
if ((length == 1) && (value._data[0] == 1))
{
return Zero;
}
numArray = sub(value._data, length, new uint[] { 1 }, 1);
num = 1;
}
else
{
numArray = add0(value._data, length, new uint[] { 1 }, 1);
num = -1;
}
return new BigInteger(num, numArray);
}
public static BigInteger operator +(BigInteger x, BigInteger y)
{
if (x._sign == y._sign)
{
return new BigInteger(x._sign, add0(x._data, x.Length, y._data, y.Length));
}
return (x - (-y));
}
public static BigInteger operator -(BigInteger x, BigInteger y)
{
uint[] array;
int compare = Compare(x, y);
if (compare != 0)
{
if (x._sign != y._sign)
{
return new BigInteger(compare, add0(x._data, x.Length, y._data, y.Length));
}
switch ((compare * x._sign))
{
case -1:
array = sub(y._data, y.Length, x._data, x.Length);
return new BigInteger(compare, array);
case 1:
array = sub(x._data, x.Length, y._data, y.Length);
return new BigInteger(compare, array);
default:
break;
}
}
return Zero;
}
public static BigInteger operator *(BigInteger x, BigInteger y)
{
return Multiply(x, y);
}
public static BigInteger operator %(BigInteger x, BigInteger y)
{
BigInteger result;
if ((x._sign == y._sign) && (x.Length < y.Length))
{
return x;
}
DivRem(x, y, out result);
return result;
}
public static BigInteger operator /(BigInteger dividend, BigInteger divisor)
{
BigInteger integer;
return DivRem(dividend, divisor, out integer);
}
public static bool operator ==(BigInteger x, BigInteger y)
{
return (Compare(x, y) == 0);
}
public static bool operator !=(BigInteger x, BigInteger y)
{
return (Compare(x, y) != 0);
}
public static bool operator <(BigInteger x, BigInteger y)
{
return (Compare(x, y) < 0);
}
public static bool operator <=(BigInteger x, BigInteger y)
{
return (Compare(x, y) <= 0);
}
public static bool operator >(BigInteger x, BigInteger y)
{
return (Compare(x, y) > 0);
}
public static bool operator >=(BigInteger x, BigInteger y)
{
return (Compare(x, y) >= 0);
}
public static explicit operator byte(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow Byte");
}
if (value._data[0] > 0xff)
{
throw new OverflowException("Overflow Byte");
}
if (value._sign < 0)
{
throw new OverflowException("Overflow Byte");
}
return (byte)value._data[0];
}
[CLSCompliant(false)]
public static explicit operator sbyte(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow sbyte");
}
if (value._data[0] > 0x80)
{
throw new OverflowException("Overflow sbyte");
}
if ((value._data[0] == 0x80) && (value._sign == 1))
{
throw new OverflowException("Overflow sbyte");
}
sbyte num = (sbyte)value._data[0];
return (sbyte)(num * ((sbyte)value._sign));
}
public static explicit operator short(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow int16");
}
if (value._data[0] > 0x8000)
{
throw new OverflowException("Overflow int16");
}
if ((value._data[0] == 0x8000) && (value._sign == 1))
{
throw new OverflowException("Overflow int16");
}
short num = (short)value._data[0];
return (short)(num * value._sign);
}
[CLSCompliant(false)]
public static explicit operator ushort(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow uint16");
}
if (value._data[0] > 0xffff)
{
throw new OverflowException("Overflow uint16");
}
if (value._sign < 0)
{
throw new OverflowException("Overflow uint16");
}
return (ushort)value._data[0];
}
public static explicit operator int(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow int32");
}
if (value._data[0] > 0x80000000)
{
throw new OverflowException("Overflow int32");
}
if ((value._data[0] == 0x80000000) && (value._sign == 1))
{
throw new OverflowException("Overflow int32");
}
int num = (int)value._data[0];
return (num * value._sign);
}
[CLSCompliant(false)]
public static explicit operator uint(BigInteger value)
{
if (value._sign == 0)
{
return 0;
}
if (value.Length > 1)
{
throw new OverflowException("Overflow uint32");
}
if (value._sign < 0)
{
throw new OverflowException("Overflow uint32");
}
return value._data[0];
}
public static explicit operator long(BigInteger value)
{
if (value._sign == 0)
{
return 0L;
}
if (value.Length > 2)
{
throw new OverflowException("Overflow int64");
}
if (value.Length == 1)
{
return (value._sign * value._data[0]);
}
ulong num2 = (value._data[1] << 0x20) | value._data[0];
if (num2 > 9223372036854775808L)
{
throw new OverflowException("Overflow int64");
}
if ((num2 == 9223372036854775808L) && (value._sign == 1))
{
throw new OverflowException("Overflow int64");
}
return (long)num2 * (long)value._sign;
}
[CLSCompliant(false)]
public static explicit operator ulong(BigInteger value)
{
ulong num = 0L;
if (value._sign == 0)
{
return 0L;
}
if (value._sign < 0)
{
throw new OverflowException("Overflow uint64");
}
if (value.Length > 2)
{
throw new OverflowException("Overflow uint64");
}
num = value._data[0];
if (value.Length > 1)
{
num |= value._data[1] << 0x20;
}
return num;
}
public static explicit operator float(BigInteger value)
{
float num;
NumberFormatInfo numberFormat = CultureInfo.InvariantCulture.NumberFormat;
if (!float.TryParse(value.ToString(10, false, numberFormat), NumberStyles.Number, (IFormatProvider)numberFormat, out num))
{
throw new OverflowException("Overflow single");
}
return num;
}
public static explicit operator double(BigInteger value)
{
double num;
NumberFormatInfo numberFormat = CultureInfo.InvariantCulture.NumberFormat;
if (!double.TryParse(value.ToString(10, false, numberFormat), NumberStyles.Number, (IFormatProvider)numberFormat, out num))
{
throw new OverflowException("Overflow double");
}
return num;
}
public static explicit operator decimal(BigInteger value)
{
if (value._sign == 0)
{
return 0M;
}
int length = value.Length;
if (length > 3)
{
throw new OverflowException("Overflow Decimal");
}
int lo = 0;
int mid = 0;
int hi = 0;
if (length > 2)
{
hi = (int)value._data[2];
}
if (length > 1)
{
mid = (int)value._data[1];
}
if (length > 0)
{
lo = (int)value._data[0];
}
return new decimal(lo, mid, hi, value._sign < 0, 0);
}
public static explicit operator BigInteger(float value)
{
return new BigInteger(value);
}
public static explicit operator BigInteger(double value)
{
return new BigInteger(value);
}
public static explicit operator BigInteger(decimal value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(byte value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(sbyte value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(short value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(ushort value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(int value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(uint value)
{
return new BigInteger(value);
}
public static implicit operator BigInteger(long value)
{
return new BigInteger(value);
}
[CLSCompliant(false)]
public static implicit operator BigInteger(ulong value)
{
return new BigInteger(value);
}
#endregion
#region Instance Properties
public int Sign
{
get
{
return this._sign;
}
}
private int Length
{
get
{
if (this._length == -1)
{
this._length = GetLength(this._data);
}
return this._length;
}
}
#endregion
#region Instance Methods
private BigInteger Square()
{
return (this * this);
}
public byte[] ToByteArray()
{
bool flag;
return this.ToByteArray(out flag);
}
public byte[] ToByteArray(out bool isNegative)
{
int length = this.Length;
byte[] result = new byte[length * 4];
Buffer.BlockCopy(this._data, 0, result, 0, length * 4);
isNegative = this._sign == -1;
return result;
}
private BigInteger RestrictTo(int numDigits)
{
int length = Math.Min(numDigits, this.Length);
if (length == this.Length)
{
return this;
}
BigInteger result = new BigInteger(this._sign, this._data);
result._length = length;
return result;
}
public string ToString(string format)
{
return this.ToString(format, CultureInfo.CurrentCulture);
}
public string ToString(IFormatProvider formatProvider)
{
if (formatProvider == null)
{
formatProvider = CultureInfo.CurrentCulture;
}
return this.ToString(10, false, (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo)));
}
public string ToString(string format, IFormatProvider formatProvider)
{
if (formatProvider == null)
{
formatProvider = CultureInfo.CurrentCulture;
}
uint radix = 10;
bool useCapitalHexDigits = false;
if (!string.IsNullOrEmpty(format))
{
char ch = format[0];
switch (ch)
{
case 'X':
case 'x':
radix = 0x10;
useCapitalHexDigits = ch == 'X';
break;
default:
if (((ch != 'G') && (ch != 'g')) && ((ch != 'D') && (ch != 'd')))
{
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Currently not supported format: {0}", new object[] { format }));
}
break;
}
}
return this.ToString(radix, useCapitalHexDigits, (NumberFormatInfo)formatProvider.GetFormat(typeof(NumberFormatInfo)));
}
public override string ToString()
{
return this.ToString(10, false, CultureInfo.CurrentCulture.NumberFormat);
}
private string ToString(uint radix, bool useCapitalHexDigits, NumberFormatInfo info)
{
if (this._sign == 0)
{
return "0";
}
int length = this.Length;
List<uint> list = new List<uint>();
uint[] n = copy(this._data);
int nl = this.Length;
uint d = groupRadixValues[radix];
while (nl > 0)
{
uint item = div(n, ref nl, d);
list.Add(item);
}
StringBuilder sb = new StringBuilder();
if (this._sign == -1)
{
sb.Append(info.NegativeSign);
}
int index = list.Count - 1;
char[] tmp = new char[maxCharsPerDigit[radix]];
AppendRadix(list[index--], radix, useCapitalHexDigits, tmp, sb, false);
while (index >= 0)
{
AppendRadix(list[index--], radix, useCapitalHexDigits, tmp, sb, true);
}
return sb.ToString();
}
public override int GetHashCode()
{
if (this._sign == 0)
{
return 0;
}
return (int)this._data[0];
}
public bool Equals(BigInteger other)
{
if (this._sign != other._sign)
{
return false;
}
int length = this.Length;
int otherLength = other.Length;
if (length != otherLength)
{
return false;
}
for (uint i = 0; i < length; i++)
{
if (this._data[i] != other._data[i])
{
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return (((obj != null) && (obj is BigInteger)) && this.Equals((BigInteger)obj));
}
public int CompareTo(BigInteger other)
{
return Compare(this, other);
}
public int CompareTo(object obj)
{
if (obj == null)
{
return 1;
}
if (!(obj is BigInteger))
{
throw new ArgumentException("MustBeBigInt");
}
return Compare(this, (BigInteger)obj);
}
#endregion
}