private static void Multiply(BigInt a, int b, ref BigInt c) { if (b == 0) { c.Clear(); return; } int carry = 0, product = 0; int size = a.Size; int newSize = 0; for (int index = 0; index < size; index++) { product = b * a.GetDigit(index) + carry; carry = product / m_base; c.SetDigit(index, (byte)(product % m_base), ref newSize); } if (carry != 0) { byte[] bytes = BitConverter.GetBytes(carry); for (int index = 0; index < bytes.Length; index++) { c.SetDigit(size + index, bytes[index], ref newSize); } } c.Size = newSize; }
private static void Multiply(BigInt a, int b, ref BigInt c) { if (b == 0) { c.Clear(); } else { int num = 0; int num2 = 0; int size = a.Size; int num4 = 0; for (int i = 0; i < size; i++) { num2 = (b * a.GetDigit(i)) + num; num = num2 / 0x100; c.SetDigit(i, (byte)(num2 % 0x100), ref num4); } if (num != 0) { byte[] bytes = BitConverter.GetBytes(num); for (int j = 0; j < bytes.Length; j++) { c.SetDigit(size + j, bytes[j], ref num4); } } c.Size = num4; } }
// // Subtracts b from a and outputs the result in c. // internal static void Subtract(BigInt a, BigInt b, ref BigInt c) { byte borrow = 0; int diff = 0; if (a < b) { Subtract(b, a, ref c); Negate(ref c); return; } int index = 0; int size = a.Size; int newSize = 0; for (index = 0; index < size; index++) { diff = a.GetDigit(index) - b.GetDigit(index) - borrow; borrow = 0; if (diff < 0) { diff += m_base; borrow = 1; } c.SetDigit(index, (byte)(diff & 0xFF), ref newSize); } c.Size = newSize; }
internal static void Subtract(BigInt a, BigInt b, ref BigInt c) { byte num = 0; int num2 = 0; if (a < b) { Subtract(b, a, ref c); Negate(ref c); } else { int index = 0; int size = a.Size; int num5 = 0; for (index = 0; index < size; index++) { num2 = (a.GetDigit(index) - b.GetDigit(index)) - num; num = 0; if (num2 < 0) { num2 += 0x100; num = 1; } c.SetDigit(index, (byte)(num2 & 0xff), ref num5); } c.Size = num5; } }
internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) { if (numerator < denominator) { quotient.Clear(); remainder.CopyFrom(numerator); } else if (numerator == denominator) { quotient.Clear(); quotient.SetDigit(0, 1); remainder.Clear(); } else { BigInt a = new BigInt(); a.CopyFrom(numerator); BigInt num2 = new BigInt(); num2.CopyFrom(denominator); uint num3 = 0; while (num2.Size < a.Size) { num2.Multiply(0x100); num3++; } if (num2 > a) { num2.Divide(0x100); num3--; } int num4 = 0; int digit = 0; int b = 0; BigInt c = new BigInt(); quotient.Clear(); for (int i = 0; i <= num3; i++) { num4 = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2)); digit = num2.GetDigit(num2.Size - 1); b = num4 / digit; if (b >= 0x100) { b = 0xff; } Multiply(num2, b, ref c); while (c > a) { b--; Multiply(num2, b, ref c); } quotient.Multiply(0x100); Add(quotient, (byte)b, ref quotient); Subtract(a, c, ref a); num2.Divide(0x100); } remainder.CopyFrom(a); } }
internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) { if (numerator < denominator) { quotient.Clear(); remainder.CopyFrom(numerator); } else if (numerator == denominator) { quotient.Clear(); quotient.SetDigit(0, 1); remainder.Clear(); } else { BigInt a = new BigInt(); a.CopyFrom(numerator); BigInt num2 = new BigInt(); num2.CopyFrom(denominator); uint num3 = 0; while (num2.Size < a.Size) { num2.Multiply(0x100); num3++; } if (num2 > a) { num2.Divide(0x100); num3--; } int num4 = 0; int digit = 0; int b = 0; BigInt c = new BigInt(); quotient.Clear(); for (int i = 0; i <= num3; i++) { num4 = (a.Size == num2.Size) ? a.GetDigit(a.Size - 1) : ((0x100 * a.GetDigit(a.Size - 1)) + a.GetDigit(a.Size - 2)); digit = num2.GetDigit(num2.Size - 1); b = num4 / digit; if (b >= 0x100) { b = 0xff; } Multiply(num2, b, ref c); while (c > a) { b--; Multiply(num2, b, ref c); } quotient.Multiply(0x100); Add(quotient, (byte) b, ref quotient); Subtract(a, c, ref a); num2.Divide(0x100); } remainder.CopyFrom(a); } }
internal static void Add(BigInt a, byte b, ref BigInt c) { byte digit = b; int num2 = 0; int size = a.Size; int num4 = 0; for (int i = 0; i < size; i++) { num2 = a.GetDigit(i) + digit; c.SetDigit(i, (byte) (num2 & 0xff), ref num4); digit = (byte) ((num2 >> 8) & 0xff); } if (digit != 0) { c.SetDigit(a.Size, digit, ref num4); } c.Size = num4; }
// // Negates a BigInt value. Each byte is complemented, then we add 1 to it. // internal static void Negate(ref BigInt a) { int newSize = 0; for (int index = 0; index < m_maxbytes; index++) { a.SetDigit(index, (byte)(~a.GetDigit(index) & 0xFF), ref newSize); } for (int index = 0; index < m_maxbytes; index++) { a.SetDigit(index, (byte)(a.GetDigit(index) + 1), ref newSize); if ((a.GetDigit(index) & 0xFF) != 0) { break; } a.SetDigit(index, (byte)(a.GetDigit(index) & 0xFF), ref newSize); } a.Size = newSize; }
internal static void Negate(ref BigInt a) { int size = 0; for (int i = 0; i < 0x80; i++) { a.SetDigit(i, (byte)(~a.GetDigit(i) & 0xff), ref size); } for (int j = 0; j < 0x80; j++) { a.SetDigit(j, (byte)(a.GetDigit(j) + 1), ref size); if ((a.GetDigit(j) & 0xff) != 0) { break; } a.SetDigit(j, (byte)(a.GetDigit(j) & 0xff), ref size); } a.Size = size; }
internal static void Add(BigInt a, byte b, ref BigInt c) { byte digit = b; int num2 = 0; int size = a.Size; int num4 = 0; for (int i = 0; i < size; i++) { num2 = a.GetDigit(i) + digit; c.SetDigit(i, (byte)(num2 & 0xff), ref num4); digit = (byte)((num2 >> 8) & 0xff); } if (digit != 0) { c.SetDigit(a.Size, digit, ref num4); } c.Size = num4; }
// // Adds a and b and outputs the result in c. // internal static void Add(BigInt a, byte b, ref BigInt c) { byte carry = b; int sum = 0; int size = a.Size; int newSize = 0; for (int index = 0; index < size; index++) { sum = a.GetDigit(index) + carry; c.SetDigit(index, (byte)(sum & 0xFF), ref newSize); carry = (byte)((sum >> 8) & 0xFF); } if (carry != 0) { c.SetDigit(a.Size, carry, ref newSize); } c.Size = newSize; }
// // Integer division of one BigInt by another. // internal static void Divide (BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) { // Avoid extra computations in special cases. if (numerator < denominator) { quotient.Clear(); remainder.CopyFrom(numerator); return; } if (numerator == denominator) { quotient.Clear(); quotient.SetDigit(0, 1); remainder.Clear(); return; } BigInt dividend = new BigInt(); dividend.CopyFrom(numerator); BigInt divisor = new BigInt(); divisor.CopyFrom(denominator); uint zeroCount = 0; // We pad the divisor with zeros until its size equals that of the dividend. while (divisor.Size < dividend.Size) { divisor.Multiply(m_base); zeroCount++; } if (divisor > dividend) { divisor.Divide(m_base); zeroCount--; } // Use school division techniques, make a guess for how many times // divisor goes into dividend, making adjustment if necessary. int a = 0; int b = 0; int c = 0; BigInt hold = new BigInt(); quotient.Clear(); for (int index = 0; index <= zeroCount; index++) { a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) : m_base * dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2); b = divisor.GetDigit(divisor.Size - 1); c = a / b; if (c >= m_base) c = 0xFF; Multiply(divisor, c, ref hold); while (hold > dividend) { c--; Multiply(divisor, c, ref hold); } quotient.Multiply(m_base); Add(quotient, (byte) c, ref quotient); Subtract(dividend, hold, ref dividend); divisor.Divide(m_base); } remainder.CopyFrom(dividend); }
internal static void Negate(ref BigInt a) { int size = 0; for (int i = 0; i < 0x80; i++) { a.SetDigit(i, (byte) (~a.GetDigit(i) & 0xff), ref size); } for (int j = 0; j < 0x80; j++) { a.SetDigit(j, (byte) (a.GetDigit(j) + 1), ref size); if ((a.GetDigit(j) & 0xff) != 0) { break; } a.SetDigit(j, (byte) (a.GetDigit(j) & 0xff), ref size); } a.Size = size; }
private static void Multiply (BigInt a, int b, ref BigInt c) { if (b == 0) { c.Clear(); return; } int carry = 0, product = 0; int size = a.Size; int newSize = 0; for (int index = 0; index < size; index++) { product = b * a.GetDigit(index) + carry; carry = product / m_base; c.SetDigit(index, (byte) (product % m_base), ref newSize); } if (carry != 0) { byte[] bytes = BitConverter.GetBytes(carry); for (int index = 0; index < bytes.Length; index++) { c.SetDigit(size + index, bytes[index], ref newSize); } } c.Size = newSize; }
// // Subtracts b from a and outputs the result in c. // internal static void Subtract (BigInt a, BigInt b, ref BigInt c) { byte borrow = 0; int diff = 0; if (a < b) { Subtract(b, a, ref c); Negate(ref c); return; } int index = 0; int size = a.Size; int newSize = 0; for (index = 0; index < size; index++) { diff = a.GetDigit(index) - b.GetDigit(index) - borrow; borrow = 0; if (diff < 0) { diff += m_base; borrow = 1; } c.SetDigit(index, (byte) (diff & 0xFF), ref newSize); } c.Size = newSize; }
// // Negates a BigInt value. Each byte is complemented, then we add 1 to it. // internal static void Negate (ref BigInt a) { int newSize = 0; for (int index = 0; index < m_maxbytes; index++) { a.SetDigit(index, (byte) (~a.GetDigit(index) & 0xFF), ref newSize); } for (int index = 0; index < m_maxbytes; index++) { a.SetDigit(index, (byte) (a.GetDigit(index) + 1), ref newSize); if ((a.GetDigit(index) & 0xFF) != 0) break; a.SetDigit(index, (byte) (a.GetDigit(index) & 0xFF), ref newSize); } a.Size = newSize; }
// // Adds a and b and outputs the result in c. // internal static void Add (BigInt a, byte b, ref BigInt c) { byte carry = b; int sum = 0; int size = a.Size; int newSize = 0; for (int index = 0; index < size; index++) { sum = a.GetDigit(index) + carry; c.SetDigit(index, (byte) (sum & 0xFF), ref newSize); carry = (byte) ((sum >> 8) & 0xFF); } if (carry != 0) c.SetDigit(a.Size, carry, ref newSize); c.Size = newSize; }
internal static void Subtract(BigInt a, BigInt b, ref BigInt c) { byte num = 0; int num2 = 0; if (a < b) { Subtract(b, a, ref c); Negate(ref c); } else { int index = 0; int size = a.Size; int num5 = 0; for (index = 0; index < size; index++) { num2 = (a.GetDigit(index) - b.GetDigit(index)) - num; num = 0; if (num2 < 0) { num2 += 0x100; num = 1; } c.SetDigit(index, (byte) (num2 & 0xff), ref num5); } c.Size = num5; } }
// // Integer division of one BigInt by another. // internal static void Divide(BigInt numerator, BigInt denominator, ref BigInt quotient, ref BigInt remainder) { // Avoid extra computations in special cases. if (numerator < denominator) { quotient.Clear(); remainder.CopyFrom(numerator); return; } if (numerator == denominator) { quotient.Clear(); quotient.SetDigit(0, 1); remainder.Clear(); return; } BigInt dividend = new BigInt(); dividend.CopyFrom(numerator); BigInt divisor = new BigInt(); divisor.CopyFrom(denominator); uint zeroCount = 0; // We pad the divisor with zeros until its size equals that of the dividend. while (divisor.Size < dividend.Size) { divisor.Multiply(m_base); zeroCount++; } if (divisor > dividend) { divisor.Divide(m_base); zeroCount--; } // Use school division techniques, make a guess for how many times // divisor goes into dividend, making adjustment if necessary. int a = 0; int b = 0; int c = 0; BigInt hold = new BigInt(); quotient.Clear(); for (int index = 0; index <= zeroCount; index++) { a = dividend.Size == divisor.Size ? dividend.GetDigit(dividend.Size - 1) : m_base *dividend.GetDigit(dividend.Size - 1) + dividend.GetDigit(dividend.Size - 2); b = divisor.GetDigit(divisor.Size - 1); c = a / b; if (c >= m_base) { c = 0xFF; } Multiply(divisor, c, ref hold); while (hold > dividend) { c--; Multiply(divisor, c, ref hold); } quotient.Multiply(m_base); Add(quotient, (byte)c, ref quotient); Subtract(dividend, hold, ref dividend); divisor.Divide(m_base); } remainder.CopyFrom(dividend); }
private static void Multiply(BigInt a, int b, ref BigInt c) { if (b == 0) { c.Clear(); } else { int num = 0; int num2 = 0; int size = a.Size; int num4 = 0; for (int i = 0; i < size; i++) { num2 = (b * a.GetDigit(i)) + num; num = num2 / 0x100; c.SetDigit(i, (byte) (num2 % 0x100), ref num4); } if (num != 0) { byte[] bytes = BitConverter.GetBytes(num); for (int j = 0; j < bytes.Length; j++) { c.SetDigit(size + j, bytes[j], ref num4); } } c.Size = num4; } }